Как использовать команду sed для добавления строки перед строкой шаблона? - PullRequest
9 голосов
/ 08 июля 2011

Я хочу использовать sed для изменения моего файла с именем "baz".

Когда я ищу шаблон foo, foo находится не в начале или конце строки, я хочу добавить строку перед foo, как я могу это сделать с помощью sed?

Input file named baz:
blah_foo_blahblahblah
blah_foo_blahblahblah
blah_foo_blahblahblah
blah_foo_blahblahblah

Output file 
blah_barfoo_blahblahblah
blah_barfoo_blahblahblah
blah_barfoo_blahblahblah
blah_barfoo_blahblahblah

Ответы [ 3 ]

16 голосов
/ 08 июля 2011

Вы можете просто использовать что-то вроде:

sed 's/foo/barfoo/g' baz

(g в конце означает глобальный, каждое вхождение в каждой строке, а не только в первой).

Для произвольного (а не фиксированного) шаблона, такого как foo[0-9], вы можете использовать группы захвата следующим образом:

pax$ echo 'xyz fooA abc
xyz foo5 abc
xyz fooB abc' | sed 's/\(foo[0-9]\)/bar\1/g'

xyz fooA abc
xyz barfoo5 abc
xyz fooB abc

В скобках указан фактический текст, соответствующий шаблону, а \1 использует его в подстановке.

Вы можете использовать произвольно сложные шаблоны с этим, в том числе гарантируя, что вы соответствуете только полные слова. Например, изменение шаблона только в том случае, если он сразу окружен границей слова:

pax$ echo 'xyz fooA abc
xyz foo5 abc foo77 qqq xfoo4 zzz
xyz fooB abc' | sed 's/\(\bfoo[0-9]\b\)/bar\1/g'

xyz fooA abc
xyz barfoo5 abc foo77 qqq xfoo4 zzz
xyz fooB abc

Что касается работы групп захвата, вы можете использовать скобки для хранения текста, соответствующего шаблону, для последующего использования при замене. Захваченные идентификаторы основаны на чтении символов ( слева направо, поэтому регулярное выражение (я отбросил управляющие символы \ и немного добавил его для ясности):

( ( \S* )   ( \S* ) )
^ ^     ^   ^     ^ ^
| |     |   |     | |
| +--2--+   +--3--+ |
+---------1---------+

применительно к тексту Pax Diablo даст вам три группы:

\1 = Pax Diablo
\2 = Pax
\3 = Diablo

как показано ниже:

pax$ echo 'Pax Diablo' | sed 's/\(\(\S*\) \(\S*\)\)/[\1] [\2] [\3]/'
[Pax Diablo] [Pax] [Diablo]
3 голосов
/ 08 июля 2011

Просто замените начало строки чем-то другим.

sed '/^foo/s/^/bar/'
0 голосов
/ 06 августа 2011

Чтобы заменить или изменить все "foo", кроме начала или конца строки, я бы предложил временно заменить их в начале и конце строки на уникальное значение часового.

sed 's/^foo/____veryunlikelytoken_bol____/
  s/foo$/____veryunlikelytoken_eol____/
  s/foo/bar&/g
  s/^____veryunlikelytoken_bol____/foo/
  s/____veryunlikelytoken_eol____$/foo/'

В sed нет способа указать «здесь не может быть совпадений». В регулярных выражениях Perl и производных (то есть в языках, которые заимствованы из регулярных выражений Perl, не обязательно в языках, производных от Perl) у вас есть различные отрицательные утверждения, поэтому вы можете сделать что-то вроде

perl -pe 's/(?!^)foo(?!$)/barfoo/g'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...