Делает. действительно соответствует любому персонажу? - PullRequest
10 голосов
/ 13 марта 2012

Я использую очень простой sed-скрипт для удаления комментариев: sed -e 's/--.*$//'

Работает отлично, пока в комментарии не присутствуют символы не ascii, например: -- °. Эта строка не соответствует регулярному выражению и не подставляется.

Есть идеи, как заставить . действительно соответствовать любому персонажу?


Решение:

Поскольку file говорит, что это текст iso8859, переменная среда LANG должна быть изменена перед вызовом sed: LANG=iso8859 sed -e 's/--.*//' -

Ответы [ 3 ]

5 голосов
/ 13 марта 2012

Это работает для меня. Вероятно, это проблема кодировки символов.

Это может помочь:

3 голосов
/ 16 января 2018

@ julio-guerra: я столкнулся с подобной ситуацией, пытаясь удалить строки, такие как следующие (обратите внимание на символ Æ):

--MP_/yZa.b._zhqt9OhfqzaÆC

в файле, используя

sed 's/^--MP_.*$//g' my_file

Кодировка файла, указанная командой Linux file, была

    file my_file: ISO-8859 text, with very long lines
 file -b my_file: ISO-8859 text, with very long lines
file -bi my_file: text/plain; charset=iso-8859-1

Я попробовал ваше решение (умное!) С различными перестановками; например.,

LANG=ISO-8859 sed 's/^--MP_.*$//g' my_file

но ни один из них не работал. Я нашел два обходных пути:

  1. Сработало следующее выражение Perl, т.е. удалили эту строку:

perl -pe 's/^--MP_.*$//g' my_file

[Описание параметров командной строки -pe см. В ответе StackOverflow:

флаги Perl -pe, -pi, -p, -w, -d, -i, -t? ]

  1. В качестве альтернативы, после преобразования кодировки файла в UTF-8 сработало выражение sed (символ Æ остался, но теперь был закодирован в UTF8):

iconv -f iso-8859-1 -t utf-8 my_file > my_file.utf8

Поскольку я работаю с большим количеством (1000) писем с различными кодировками, которые подвергаются промежуточной обработке (преобразования с использованием bash-скриптов в UTF-8 не всегда работают), для моих целей приведенное выше «решение 1», вероятно, будет наиболее надежное решение.

Примечания:

  • sed (GNU sed) 4.4
  • Perl v5.26.1 построен для x86_64-linux-thread-multi
  • Система Arch Linux x86_64
0 голосов
/ 16 января 2018

В документации команды GNU sed z упоминается этот эффект (мой акцент):

Эта команда очищает содержимое пространства шаблонов.Обычно это то же самое, что 's /.*//', но более эффективно и работает при наличии недопустимых многобайтовых последовательностей во входном потоке.POSIX требует, чтобы такие последовательности не соответствовали '.' , так что в большинстве многобайтовых локалей (включая UTF-) нет переносимого способа очистки буферов sed в середине скрипта.8 локалей).

Вероятно, вы используете sed в UTF-8 (или другой многобайтовой) локали.Вы захотите установить LC_CTYPE (это более точно, чем LANG и не повлияет на перевод сообщений об ошибках. Допустимые имена локалей обычно выглядят как en.iso88591 или (для местоположения в вашем профиле) fr_FR.iso88591, а не только сама кодировка - вы можете увидеть полный список с помощью locale -a.

Пример:

LC_CTYPE=fr_FR.iso88591 sed -e 's/--.*//'

В качестве альтернативы, если вы знаете, что без комментариевчасти строки содержат только ASCII, вы можете разбить строку на маркер комментария, распечатать первую часть и отбросить оставшуюся часть:

sed -e 's/--/\n/' -e 'P' -e 'd'
...