sed (на osx Snow Leopard) с BRE '.' не соответствует символу › ascii 127

Я использую sed на Mac OS X Snow Leopard.

sed является/должен быть BSD sed (справочная страница датирована 10 мая 2005 г.) справочная страница гласит:

The sed utility is expected to be a superset of 
the IEEE Std 1003.2 (``POSIX.2'') specification.

Когда я пытаюсь заменить, а входной поток содержит символы, превышающие ascii 127, точка не соответствует этому символу.

e.g.

echo -e "a001\0001a - a127\0177a - a128\0200a - a255\0377a - a061\0075a" \
| sed -e 's/a[0-9]\{3\}.a/match/g;' ;
echo "result: $?";

результаты на выходе:

match - match - a128?a - a255?a - match
result: 0

В Os X Maverick (с той же страницей руководства) результат дает ошибку:

sed: RE error: illegal byte sequence
result: 1

В системе Linux Mint 13 возвращается та же инструкция (мое ожидание):

match - match - match - match - match
result: 0

согласно http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html#tag_09_03 '.' должно соответствовать

"any character in the supported character set except NUL".

Если запустить эту аналогичную команду (версия gsed 4.2.1 на OS X Snow Leopard):

echo -e "a001\0001a - a127\0177a - a128\0200a - a255\0377a - a061\0075a"\
| gsed -e 's/a[0-9]\{3\}.a/match/g;';
echo "result: $?";

Я получаю тот же (для меня неожиданный) результат:

match - match - a128?a - a255?a - match
result: 0
  1. у кого-нибудь еще такое же поведение?
  2. можете объяснить почему? (это ошибка в BSD??) и/или как обойти/исправить? Я могу только догадываться, что это связано с "supported character set", который тогда будет другим в разных системах.... Тем более, что в SL-системе и BSD sed, и GNU sed ведут себя одинаково. Однако я уже проверил и изменил свой env: В системе SL:

    $> env | grep '^L'
    LANG=en_US.UTF-8
    LANGUAGE=en_US:en
    LC_CTYPE=UTF-8
    

    И в системе Mint:

    $user@Mint > env | grep '^L'
    LANG=en_US.UTF-8
    LANGUAGE=en_US:en
    LC_CTYPE=UTF-8
    

person liselorev    schedule 19.11.2013    source источник


Ответы (1)


Ваша локаль - UTF-8, но последовательность байтов, которую вы повторяете, недействительна в UTF-8 из-за \0200a и \0377a. Если вы используете набор LC_ALL=en_US.ISO8859-1 (iso-latin-1), то он работает нормально, потому что результатом echo является допустимая строка iso-latin-1.

person F'x    schedule 19.11.2013
comment
Обратите внимание, что LC_ALL должен быть установлен в среде команды sed. Этого можно добиться, задав его в оболочке и экспортировав его (export LC_ALL=en_US.ISO8859-1 — задает его для оболочки и всех команд, выполняемых оболочкой) или используя его в качестве префикса для команды sed (LC_ALL=en_US.ISO8859-1 sed ... — задает только для sed сама команда). - person Gordon Davisson; 19.11.2013