2010-12-10 3 views
60

Я пытаюсь использовать SED для извлечения текста из файла журнала.Нечувствительный к регистру поиск и замена с помощью sed

я могу сделать поиск и заменить без особых проблем:

sed 's/foo/bar/' mylog.txt

Однако, я хочу, чтобы сделать поиск без учета регистра. Из того, что я гугле, это выглядит как добавление «я» к концу команды должны работать:

sed 's/foo/bar/i' mylog.txt

Однако, это дает мне сообщение об ошибке:

sed: 1: "s/foo/bar/i": bad flag in substitute command: 'i'

Что здесь не так, и как я могу это исправить?

Я нахожусь на OS X, в случае, если это имеет значение.

+0

Вы пробовали капитал 'I'? – Lazer

+0

@Lazer: Я сделал, но это не сработало. Меня сильно забивают, что я подаю заявление о помощи на SO. :-( –

+2

Можете ли вы попробовать обновить свою копию sed? 'I' является расширением GNU, которое может быть недоступно с вашей копией sed. – Lazer

ответ

53

Чтобы было ясно: На MacOS (OS X) - как Сьерра (10.12) - sed - который является BSD реализация - не поддерживает регистронезависимым соответствие - трудно поверить, , но правда. formerly accepted answer, который сам показывает команду GNUsed, получивший этот статус из-за решения perl, упомянутого в комментариях.

Чтобы сделать это решения Perl работы с иностранными символами, а, с помощью UTF-8, использовать что-то вроде:

perl -C -Mutf8 -pe 's/öœ/oo/i' <<< "FÖŒ" # -> "Foo" 
  • -C включает поддержку UTF-8 для потоков и файлов, предполагая, что текущий язык - это UTF-8.
  • -Mutf8 говорит Perl интерпретировать исходный код в UTF-8 (в данном случае, строка передается -pe) - это более короткий эквивалент более развернутого -e 'use utf8;' - спасибо, @Mark Рид.

(Обратите внимание, что с помощью awk не вариант либо как awk на OS X (т.е. BWK AWK, иначе BSD AWK), кажется, совершенно не знают о локалей в целом - его tolower() и toupper() функции игнорируют иностранные символы (и sub()/gsub() не учитывается нечувствительность флаги, чтобы начать с).)

+0

В командной строке 'perl' вы всегда можете использовать' -mblah' вместо '-e 'use blah''. –

+0

Typo - должен быть прописным, чтобы этот работал. 'perl -C -Mutf8 -pe 's/öœ/oo/i' <<<" FÖŒ "# => Foo' –

+0

@MarkReed: Спасибо - я обновил ответ. – mklement0

52

Заглавие «Я».

sed 's/foo/bar/I' file 
+2

Я тоже это видел и пробовал ... но я все равно получаю такое же сообщение об ошибке. –

+13

У BSD sed есть много ограничений, похоже. Я бы сделал это в PERL (т. Е. Perl -pe 's/foo/bar/i'), если это так. –

+0

Ваша команда perl сработала. Я дам вам преимущество. –

1

Мак версия sed кажется немного ограниченным.Один из способов обойти это использовать Линукс контейнер (через Докер), который имеет годную к употреблению версии sed:

cat your_file.txt | docker run -i busybox /bin/sed -r 's/[0-9]{4}/****/Ig' 
+0

Это особенно страшная вещь. Если кто-то даже серьезно относится к этому, просто установите GNU sed локально. – ocodo

17

Другой работа вокруг sed на Mac OS X, чтобы установить gsed из MacPorts или доморощенных и затем создайте псевдоним sed='gsed'.

+0

gsed "s/a/b/Ig" работает, спасибо! Почему хороший рабочий ответ должен получить нижний предел? –

+2

этот ответ замечательный. использовал 'brew install gnu-sed', затем перешел в мой файл ~/.bash_profile и добавил псевдоним. Спасибо @davmat – ThinkBonobo

+5

Лучше сделать 'brew install gnu-sed --with-default-names' - это переопределит значение' sed' по умолчанию. – Mar0ux

-2

sed 's/string1/string2/Ig' Capital I - это опция, которая полезна для поиска строки независимо от чувствительности к регистру.

0

У меня была подобная необходимость, и пришел с этим:

эту команду, чтобы просто найти все файлы:

grep -i -l -r foo ./* 

это одно, чтобы исключить this_shell.sh (в случае, если вы поместите команду в сценарии под названием this_shell.sh), тройник вывод на консоль, чтобы посмотреть, что случилось, а затем использовать СЭД на название файла найден, чтобы заменить текст Foo с баром:

grep -i -l -r --exclude "this_shell.sh" foo ./* | tee /dev/fd/2 | while read -r x; do sed -b -i 's/foo/bar/gi' "$x"; done 

Я выбрал этот метод, так как мне не нравилось изменение всех временных меток для файлов, которые не были изменены. подача результата grep позволяет просматривать только файлы с целевым текстом (таким образом, вероятно, это может также улучшить производительность/скорость)

обязательно создайте резервную копию своих файлов & перед использованием. Может не работать в некоторых средах для файлов со встроенными пространствами. (?)

0

Если вы делаете шаблон сопоставления первый, например,/шаблон/s/хх/уу/г

, то вы хотите поставить «я» после того, как шаблон/шаблон/Is/хх/уу/g

пример: echo Fred | sed '/ fred/Is // willma/g' возвращает willma ... без I возвращает строку нетронутой (Fred)