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

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

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

Любая идея, как получить ., чтобы действительно соответствовать любому символу?


Решение:

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

Ответ 2

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

--MP_/yZa.b._zhqt9OhfqzaÆC

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

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

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

    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 командной строки -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 -t Hread-Multi
  • Система Arch Linux x86_64

Ответ 3

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

Эта команда опустошает содержимое пространства шаблонов. Это обычно      то же, что и 's/.*//', но более эффективно и работает в      наличие недопустимых многобайтовых последовательностей во входном потоке. POSIX      требует, чтобы такие последовательности не соответствовали '.', так что      нет портативного способа очистки буферов sed в середине       script в большинстве многобайтовых локалей (включая локали UTF-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'