Sed или awk для замены строки в блоке

#bash #shell #awk #sed

#bash #оболочка #awk #sed

Вопрос:

Входной файл содержит:

 [abc]  
para1=123  
para2=456  
para3=111  

[pqr]  
para1=333  
para2=765  
para3=1345  

[xyz]  
para1=888  
para2=236  
para3=964  
  

Требование сценария оболочки — заменить один параметр определенного блока
Пример: заменить para2=765 на para2=999 of block [pqr]
Пожалуйста, помогите мне, как я могу добиться этого с sed awk помощью команды or.

Комментарии:

1. Что вы сделали сами ?

Ответ №1:

Это может сработать для вас (GNU sed):

 sed '/[pqr]/,/^s*$/s/(para2=)[0-9]*/1999/' file
  

Замените число, следующее para2= в начале блока [pqr] , на пустую строку.

Ответ №2:

Идиоматическое решение awk:

 $ awk 'BEGIN{RS=""; ORS="nn"; FS=OFS="n"} $1=="[pqr]"{$3="para2=999"} 1' file
[abc]
para1=123
para2=456
para3=111

[pqr]
para1=333
para2=999
para3=1345

[xyz]
para1=888
para2=236
para3=964
  

Ответ №3:

Через sed другим способом,

 $ sed -r ':l /^[pqr]/{:loop ;n;/^$/{b l};s/(para2=).*/1999/g;b loop;}' file_name

b loop   - Using the looping concept getting the line one by one.
^[pqr] - If the corresponding pattern is found.
^$       - Represent new line only.
s/       - Replacement to particular pattern.
n        - For getting next line
  

Ответ №4:

Вот как я бы это сделал:

 awk '/^[pqr]/ {sub(/^para2=.*/,"para2=999")}1' RS= ORS="nn" file
[abc]
para1=123
para2=456
para3=111

[pqr]
para1=333
para2=999
para3=1345

[xyz]
para1=888
para2=236
para3=964
  

Установив значение RS nothing, вы выполняете awk работу в блочном режиме, разделенном пустыми строками.
Затем убедитесь, что мы находимся в правильном блоке, выполнив поиск блока, начинающегося с [pqr]
В этом блоке измените данные с para2=765 на para2=999 , затем распечатайте их.


Другой способ сделать это:

 awk '/^[pqr]/ {f=1} f amp;amp; sub(/^para2=.*/,"para2=999"){f=0}1' file
  

Установите флаг, если pqr он найден, измените данные, если флаг имеет значение true, сбросьте флаг.

Комментарии:

1. Спасибо, это помогло. Я подумал, что, если у меня нет разделителя строк между блоками? Как заменить в этом случае?

2. @user3789290 используйте последнее awk в моем примере. Для этого не требуется пробел или другие разделители.

3. Вам нужно привязать свой REs, или приведенное выше para2=76512345 значение будет заменено para2=99912345 , например. Я подозреваю, что OP просто хочет заменить para2= строку независимо от того, какое значение она имеет.

4. Произойдет Another way to do it сбой, поскольку строка para2 находится не сразу после строки [pqr], поэтому вы устанавливаете f = 0, прежде чем sub() получит шанс. Вам нужно будет записать это как awk '/^[pqr]/ {f=1} f amp;amp; sub(/^para2=.*/,"para2=999"){f=0}1' file , но затем также, возможно, позаботиться о сбросе f , когда [...] будет найден следующий шаблон. Или вы можете использовать счетчик для отслеживания количества строк после [...] строки и замены 2-й строки вместо использования sub() .

5. @EdMorton Умный способ использовать sub в качестве истинного теста, я бы сделал awk '/^[pqr]/ {f=1} f amp;amp; /^para2/ {sub(/^para2=.*/,"para2=999");f=0}1' ваш лучше, обновил.