Zamiana kropek (.) W sed

9

Tak więc aktualne pytanie brzmi - czy ktoś ma pomysł na usunięcie M-BM-postaci specjalnej bez ryzyka utraty innych postaci?

Mam ciąg tekstu:

" . . ."

to jest

space dot space dot space dot

Próbuję zastąpić wszystkie wystąpienia tego ciągu w pliku tekstowym na

"..."

to jest

dot dot dot

Próbowałem zrobić z sed:

sed -r 's:\s\.\s\.\s\.:...:g' -i sed-dots

Niestety nie zmienia to nawet pliku wejściowego. Plik: https://www.dropbox.com/s/46zmiruy3ln85a1/sed-dots

Kiedy próbuję zamienić ten sam ciąg w edytorze tekstu (używam geany), zostaje on znaleziony i zastąpiony poprawnie.

Jedynym powodem, dla którego mogę wymyślić, jest to, że niektóre (lub wszystkie) z tych pól nie są tak naprawdę spacjami, ale jakąś specjalną postacią.

Czy ktoś ma pomysł, jak znaleźć i zamienić ten ciąg na sed (lub inne narzędzie wiersza poleceń)? Przetestuj swój pomysł na moim pliku, ponieważ problem nie jest tak oczywisty, jak mógłby się wydawać - dlatego o to zapytałem.

Po użyciu cat -Amojego pliku wydaje się problem, że te spacje nie są spacjami, ale M-BM-znakiem specjalnym. Używanie dowolnego symbolu .sugerowanego do wyszukiwania nie jest dobrym pomysłem, ponieważ istnieje ryzyko, że niektóre inne znaki zostaną usunięte.

Rafał
źródło

Odpowiedzi:

10

Najpierw zacznę od przetestowania echoi wpakowania do niego sed, niż użycia prawdziwego pliku. Po drugie, możesz użyć {n}w rozszerzonym modelu wyrażenia regularnego do oznaczenia wielokrotności i limitów.

Byłeś tam właściwie, ale wyrażenie regularne oczekiwało wiodącej przestrzeni.

$ echo 'cheese . . . muffins' | sed -r 's/(\s?\.){3}/ dot dot dot/g'
cheese dot dot dot muffins

Zauważ, że \s?wciąż jest wystarczająco chciwy, aby zepsuć wyjście, więc dodałem spację do wyjścia. Możesz tego nie chcieć. Ustawiłem również miejsce jako opcjonalne, aby pasowało do wszystkich następujących elementów:

...
. ..
.. .
. . .
 . . . 

Wystarczy usunąć opcjonalną ?flagę.


Biorąc pod uwagę problem z Unicode (w komentarzach), możesz wymusić dane do ich równoważności ASCII za pomocą, iconva następnie sed:

$ iconv -f utf-8 -t ascii//translit sed-dots | sed -r 's/(\s?\.){3}/ dot dot dot/g'
Lorem ipsum dot dot dot
Some dot dot dot more text
Oli
źródło
Dziwię się, że echozalecasz używanie zamiast catowania pliku, przynajmniej jeśli cat catuje plik, wiesz, że powłoka niczego nie interpretuje, ani echo.
Flimm,
@Flimm dla prostego przykładu z kropkami, to nie jest tak naprawdę problem. Jeśli zamierzasz ładować z pliku, nie przejmuj się cat- po prostu sedzaładuj plik (na przykład OP), ale nie zapisuj w wierszu (usuń -i, abyś mógł zobaczyć i przetestować dane wyjściowe).
Oli
@Oli Działa z twoim przykładem, ale nie działa z moim plikiem (w moim pytaniu jest link). To jest problem - twoje polecenie i inni powinni działać, ale nie działają, ponieważ jest jakiś problem z tymi kropkami. Przetestuj swoje polecenie na moim pliku, a zobaczysz, że to nie działa.
Rafał
1
@Rafal Jeśli na nie spojrzysz cat -A sed-dots, zobaczysz, że „spacje” między kropkami to M-BM- znaki specjalne ... Nie wiesz, jak się tam wkradły, ale trzeba je wymienić. Jeśli nie możesz dobrze zaatakować ich, działa to: sed -r 's/(\s\..\..\.)/ dot dot dot/ig' sed-dots
Oli
@Oli To działa. Dziękuję bardzo! Czy możesz wyjaśnić składnię? Czy na pewno nie ma żadnych skutków ubocznych i nie zastąpi niczego innego? O ile widzę, RegExp dopasuje dowolny znak po kropkach. Jednak M-BM to nie jedna postać, to trzy. Więc jak to może działać?
Rafał
0

Spróbuj wykonać następujące czynności, aby zamienić wszystkie „.” Na „.”

sed -r 's/\. /\./g' -i sed-dots

Ale dla ". . ." do "..."

sed -r 's/\. \. \./\.\.\./g' -i sed-dots
Meer Borg
źródło
0

Mógłbym użyć twojego pliku, kiedy go uruchomiłem:

tr '\240' ' ' < sed-dots.txt > sed-dots.new

Działa to bez kroku konwersji:

sed 's/[[:blank:]]\.[[:blank:]]\.[[:blank:]]\./.../g' sed-dots.txt
Skrutator
źródło
To nie działa. Myślę, że powodem jest dziwna postać M-BM, którą znaleźli @Oli.
Rafał