Ответ 1
Это работает для меня. Вероятно, это проблема кодирования символов.
Это может помочь:
Я использую очень простой sed script удаление комментариев: sed -e 's/--.*$//'
Он отлично работает до тех пор, пока в комментарии не будут присутствовать символы не-ascii, например: -- °
.
Эта строка не соответствует регулярному выражению и не заменяется.
Любая идея, как получить .
, чтобы действительно соответствовать любому символу?
Решение:
Так как file
говорит, что это текст iso8859, переменная окружения LANG
должна быть изменена перед вызовом sed
:
LANG=iso8859 sed -e 's/--.*//' -
Это работает для меня. Вероятно, это проблема кодирования символов.
Это может помочь:
@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
но никто из них не работал. Я нашел два обходных пути:
Perl
сработало, т.е. удалило эту строку: perl -pe 's/^--MP_.*$//g' my_file
[Для объяснения -pe
командной строки -pe
, обратитесь к этому ответу StackOverflow:
Флаги Perl -pe, -pi, -p, -w, -d, -i, -t? ]
Æ
остался, но теперь был закодирован в UTF8): iconv -f iso-8859-1 -t utf-8 my_file > my_file.utf8
Поскольку я работаю с большим количеством (1000-х) электронных писем с различными кодировками, которые подвергаются промежуточной обработке (преобразования с использованием bash-скриптов в UTF-8 не всегда работают), для моих целей "решение 1" выше, вероятно, будет самым надежным решением.
Заметки:
В документации команды 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'