sed
подмена
Поиск…
Замена с использованием переменных оболочки
Переменные внутри одиночные кавычки '
не получает расширено POSIX совместимых оболочек, поэтому с помощью переменной оболочки в sed
подстановки требует использования двойных кавычек "
вместо одиночных кавычек '
:
$ var="he"
$ echo "hello" | sed "s/$var/XX/"
XXllo
$ var="he"
$ echo "hello" | sed 's/$var/XX/'
hello
Будьте осторожны при вводе команд при оценке переменных:
$ var='./&/;x;w/etc/passwd
> x;s/he'
$ echo "hello" | sed "s/$var/XX/"
sed: /etc/passwd: Permission denied
Если выше было выполнено как root, выход был бы неотличим от первого примера, и содержимое файла /etc/passwd
было бы уничтожено.
обратная ссылка
Используя экранированные скобки, вы можете определить группу захвата в шаблоне, который может быть повторно привязан в строке замещения с помощью \1
:
$ echo Hello world! | sed 's/\(Hello\) world!/\1 sed/'
Hello sed
С несколькими группами:
$ echo one two three | sed 's/\(one\) \(two\) \(three\)/\3 \2 \1/'
three two one
При использовании расширенных регулярных выражений (см. Дополнительные параметры ) скобки выполняют группировку по умолчанию и не должны быть экранированы:
$ echo one two three | sed -E 's/(one) (two) (three)/\3 \2 \1/'
three two one
Слова, состоящие из буквы, цифр и подчеркиваний, могут быть сопоставлены с использованием выражения [[:alnum:]_]\{1,\}
:
$ echo Hello 123 reg_exp | sed 's/\([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\)/\3 \2 \1/'
reg_exp 123 Hello
Последовательность \w
эквивалентна [[:alnum:]_]
$ echo Hello 123 reg_exp | sed 's/\(\w\w*\) \(\w\w*\) \(\w\w*\)/\3 \2 \1/'
reg_exp 123 Hello
Использование разных разделителей
POSIX / IEEE Open Group Base Specification говорит :
[2addr] s / BRE / замена / флаги
Подставьте заменяющую строку для экземпляров BRE в пространстве шаблонов. Любой символ, отличный от обратной косой черты или новой строки, может использоваться вместо косой черты, чтобы разграничить BRE и замену. В BRE и замене сам разделитель BRE может использоваться как буквенный символ, если ему предшествует обратная косая черта.
Бывают случаи, когда разделитель /
для замены sed
находится в BRE или замене, вызывая ошибки, такие как:
$ echo "2/3/4" | sed "s/2/3/X/"
sed: -e expression #1, char 7: unknown option to `s'
Для этого мы можем использовать разные разделители, такие как #
или _
или даже пробел:
$ echo "2/3/4" | sed "s#2/3#X#"
X/4
$ echo "2/3/4" | sed "s_2/3_X_"
X/4
$ echo "2/3/4" | sed "s 2/3 X "
X/4
Флаги шаблонов - замена замещения
Если мы хотим заменить только первое вхождение в строке, мы используем sed
как обычно:
$ cat example
aaaaabbbbb
aaaaaccccc
aaaaaddddd
$ sed 's/a/x/' example
xaaaabbbbb
xaaaaccccc
xaaaaddddd
Но что, если мы хотим заменить все вхождения?
Мы просто добавляем флаг g
pattern в конце:
$ sed 's/a/x/g' example
xxxxxbbbbb
xxxxxccccc
xxxxxddddd
И если мы хотим заменить одно конкретное событие, мы можем фактически указать, какой из них:
$ sed 's/a/x/3' example
aaxaabbbbb
aaxaaccccc
aaxaaddddd
/3
- /3
-е место.
Из info sed
см. Руководство GNU sed для онлайн-версии
в стандарте POSIX не указывается, что должно произойти, когда вы смешиваете модификаторы
g
и NUMBER, и в настоящее время не существует широко согласованного значения в реализацияхsed
. Для GNUsed
взаимодействие определяется как: игнорировать совпадения до NUMBERth, а затем сопоставлять и заменять все совпадения с NUMBERth on.
$ sed 's/b/y/2g' example
aaaaabyyyy
aaaaaccccc
aaaaaddddd
$ sed 's/c/z/g3' example
aaaaabbbbb
aaaaacczzz
aaaaaddddd