Замена точек (.) В седе

9

Поэтому актуальный вопрос: есть ли у кого-нибудь идея, как удалить M-BM-специальный символ, не рискуя потерять другие символы?

У меня есть строка текста:

" . . ."

это

space dot space dot space dot

Я пытаюсь заменить все вхождения этой строки в текстовом файле на

"..."

это

dot dot dot

Я пытался сделать с помощью sed:

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

К сожалению, это не меняет входной файл даже немного. Файл: https://www.dropbox.com/s/46zmiruy3ln85a1/sed-dots

Когда я пытаюсь заменить строку в текстовом редакторе (я использую geany), она обнаруживается и заменяется правильно.

Единственная причина, по которой я могу думать, состоит в том, что некоторые (или все) из этих пробелов на самом деле не пробелы, а какой-то особый символ.

Кто-нибудь есть идеи, как найти и заменить эту строку с Sed (или любой другой инструмент командной строки)? Пожалуйста, проверьте свою идею в моем файле, так как проблема не так очевидна, как может показаться - вот почему я спросил об этом.

После использования cat -Amyfile кажется, что эти пробелы не пробелы, а M-BM-специальный символ. Использование любого символа, .предложенного для поиска, не очень хорошая идея, так как есть риск, что некоторые другие символы будут удалены.

Рафал
источник

Ответы:

10

Сначала я бы начал с тестирования echoи передачи этого sed, чем с использованием реального файла. Во-вторых, вы можете использовать {n}в расширенной модели регулярных выражений, чтобы обозначить кратные и ограничения.

Вы были в значительной степени там, но ваш регулярный оператор ожидал ведущего места.

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

Обратите внимание, что \s?все еще достаточно жадный, чтобы испортить вывод, поэтому я добавил пробел к выводу. Вы можете не хотеть этого. Я также сделал пробел необязательным, поэтому он будет соответствовать всем следующим:

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

Просто удалите дополнительный ?флаг.


Учитывая вашу проблему с юникодом (в комментариях), вы можете заставить данные к их ASCII-эквивалентности, iconvа затем уложить их:

$ 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
Оли
источник
Я удивлен тем, что вы рекомендуете использовать echoвместо catting файл, по крайней мере, когда вы cat cat файл, вы знаете, что оболочка ничего не интерпретирует, и ни один не эхо.
Flimm
@Flimm для простого примера с точками, это не проблема. Если вы собираетесь загружать из файла, не беспокойтесь cat- просто sedзагрузите файл (в соответствии с примером OP), но не сохраняйте встроенный файл (удалите -i, чтобы вы могли увидеть и проверить результаты).
Оли
@Oli Это работает с вашим примером, но не работает с моим файлом (в моем вопросе есть ссылка). Это проблема - ваша команда и другие должны работать, но они не работают, так как есть некоторые проблемы с этими точками. Пожалуйста, проверьте вашу команду в моем файле, и вы увидите, что она не работает.
Rafal
1
@Rafal Если вы посмотрите, cat -A sed-dotsто увидите, что «пробелы» между точками - это специальные M-BM- символы ... Не знаю, как они туда попали, но их нужно заменить. Если вы не можете точно нацелить их, это работает: sed -r 's/(\s\..\..\.)/ dot dot dot/ig' sed-dots
Оли
@ Оли Это работает. Большое спасибо! Не могли бы вы объяснить синтаксис? Вы уверены, что он не имеет побочных эффектов и не заменит ничего другого? Насколько я вижу, этот RegExp будет соответствовать любому символу после точек. Однако М-БМ - это не один персонаж, а три. Так как это может работать?
Рафаль
0

Попробуйте следующее, чтобы заменить все "." На "."

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

Но для ". . ." на "..."

sed -r 's/\. \. \./\.\.\./g' -i sed-dots
Меер Борг
источник
0

Я мог бы использовать ваш файл, когда пробежал по нему:

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

Это работало без шага преобразования:

sed 's/[[:blank:]]\.[[:blank:]]\.[[:blank:]]\./.../g' sed-dots.txt
Scrutinizer
источник
Это не работает. Я думаю, что причина - странный персонаж M-BM, который нашел @Oli.
Рафаль