2012-04-09 2 views
1

Мне нужно заменить внутри маленького скрипта bash строку внутри файла, но ... Я получаю странные результаты.Заменить строку в файле из сценария bash

Скажем, я хочу, чтобы заменить:

<tag><![CDATA[text]]></tag> 

С:

<tag><![CDATA[replaced_text]]></tag> 

Должен ли я использовать sed? Я думаю, из-за / и [] Я получаю странные результаты ...

Что было бы лучшим способом приблизиться к этому?

ответ

3

Да, вам нужно сбежать из скобок и либо свернуть косые черты, либо использовать разные разделители.

sed 's,<tag><!\[CDATA\[text\]\]></tag>,<tag><!\[CDATA\[replaced)text\]\]></tag>,' 

Тем не менее, SGML и XML являются на самом деле не лучше, чем HTML, когда речь заходит об использовании регулярных выражений; не ожидайте, что это обобщит.

4

Perl с опцией -p работает почти так же СЕПГ и она имеет \ Q (цитата) переключатель для своих регулярных выражений:

perl -pe 's{\Q<tag><![CDATA[text]]></tag>} 
      {<tag><![CDATA[replaced_text]]></tag>}' YOUR_FILE 

И в Perl вы можете использовать различные знаки препинания ваши выражения стоять с (S {.. .} {...} в моем примере).

+1

+1 для '\ Q'. Чтобы завершить цитирование, используйте '\ E' – Gowtham

+0

+1 для литеральных строк. Это было бы еще более превосходным, если бы кто-нибудь имел ссылку на то, как избежать исходного или заменяющего текста, чтобы избежать встроенных вхождений '\ E' или других специальных последовательностей. – l0b0

0

Это должно быть достаточно:

$ echo '<tag><![CDATA[text]]></tag>' | sed 's/\[text\]/\[replaced_text\]/' 
<tag><![CDATA[replaced_text]]></tag> 


Вы также можете изменить свой / разделитель внутри СЭД на другой символ, как ,, | или %.

0

Просто используйте разделитель, кроме /, здесь я использую #:

sed -i 's#<tag><!\[CDATA\[text\]\]></tag>#<tag><![CDATA[replaced_text]]></tag>#g' filename 

-i иметь SED изменить файл вместо печати его. g предназначен для сопоставления более одного раза.

Но знаете ли вы точную строку, которую хотите сопоставить, как тег, так и текст? Например, если вы хотите, чтобы заменить текст во все с replaced_text:

perl -i -pe 's#(<tag><!\[CDATA\[)(.*?)(\]\]></tag>)#\1replaced_text\3#g' filename 

Перешел на PERL, потому что СЭД не поддерживает нежадные мультипликатор (*?).

Смежные вопросы