2013-06-25 3 views
-1

Моя первоначальная проблема заключалась в том, чтобы добавить строку в конец определенного блока в файле конфигурации.Не могу понять шаблон sed

############ 
# MY BLOCK # 
############ 
VALUE1 = XXXXX 
VALUE2 = YYYYY 
MYNEWVALUE = XXXXX  <<< I want to add this one 

############## 
# MY BLOCK 2 # 
############## 

Для этого я использовал следующий сценарий и патч в это работает безотказно (нашел его в другой должности):

sed -i -e "/# MY BLOCK #/{:a;n;/^$/!ba;i\MYNEWVALUE = XXXXX" -e '}' myfile 

Это работало отлично, когда выполняется внутри сценария оболочки, но я не могу управлять использовать его непосредственно в интерактивной оболочке (это дало мне ошибку: «! ba event not found»). Чтобы решить эту проблему, я попытался добавить «\» до «! Ba», но теперь это дало мне еще одну ошибку, которая говорит мне, что «\» - неизвестная команда.

Может ли кто-нибудь объяснить, где моя ошибка по вышеуказанной проблеме и как работает этот скрипт?

Вот мое понимание:

-i : insert new line (i think the first one is useless, am i right?) 
-e : execute this sed script (don't understand why there is a second one at the end to close the }) 
:a : begin a loop 
n : read each line with the pattern ^$ (empty lines) 
! : reverse the loop 
ba : end of the loop 

Спасибо!

+1

'-i' сокращен для' --in-place' (заменить файл ввода измененным контентом), '-e' является сокращенным для' -expression'. Чтение 'man sed' показало бы вам (и больше) вам. –

+0

Я сделал это, спасибо за ответ. Я только хотел узнать, как sed делает свою работу, так как вы можете видеть, что мои -i и -e близки к описанию человека. – Arka

ответ

0
  • :a вводит ярлык, названный a.
  • n записывает текущее пространство образца для вывода и заменяет пространство шаблонов следующей строкой ввода.
  • /^$/! означает, что линии NOT (!) blank lines in pattern space; следующий ba - это «ветвь для маркировки а», когда это совпадение (не пустая строка).
  • Если ветка не встречается, тогда вставляется вставка i.

Используйте одинарные кавычки (') вместо двойных кавычек (") на командной строке, чтобы предотвратить скорлупу от выполнения замены оболочки (в том числе„$“и„!“Символов).

+0

Спасибо за объяснение. Для «n», когда вы имеете в виду, что пишите/заменяете шаблон, действует ли он как «прочитанный»? Я имею в виду, как вы можете читать строки из простого файла? – Arka

+0

Да: вы записываете текущий «буфер» (последняя строка читает + изменения, такие как вставка) и считывает следующую строку ввода. –

1

Использование ' вместо ", чтобы избежать Баш попытаться сделать замену истории на !

Если XXXXX содержит расширение параметров оболочки или сконвертировано, вы можете сделать это следующим образом:

sed -i -e"/# $BLOCK_NAME"'#/{:a;n;/^$/!ba;i\'"$NEW_VAR = $NEW_VALUE" -e"}" myfile 

второй -e необходим для эффективной вставки новой строки для закрытия команды i. Вы могли фактически вставить перевод строки непосредственно, вместо того, чтобы:

sed -i -e"/# $BLOCK_NAME "'#/{:a;n;/^$/!ba;i\'"$NEW_VAR = $NEW_VALUE"$'\n}' myfile 
+0

Я тоже не знаю второго, я попробовал свой код, и он дал мне «sed: -e выражение # 1, char 0: unmatched' {'". Со вторым -e он работает отлично, но я не знаю, зачем он нужен. – Arka

+0

@Arka: Я снова посмотрел на него и обновил свой ответ. Извините за путаницу. – rici

0

В интерактивных оболочек, ! используется для замещения истории, так что вам нужно, чтобы избежать его:

sed -i -e "/# MY BLOCK #/{:a;n;/^\$/\!ba;i\MYNEWVALUE = XXXXX" -e '}' myfile 

вы должны также избежать $, так как он имеет особое значение внутри doublequoted строк (хотя в данном случае это нормально, потому что за ним следует /, а не Переменная имя).