[英]linux|awk|shell script modification of line with same name in many blocks
My input file has blocks like below.
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=333
para2=765
para3=1345
[xyz]
para1=888
para2=236
para3=964
现在我如何在块 pqr 中单独修改 para2 的值而不在其他块或单独的第一个块中更改值。请帮助我使用 awk 或 perl 或 sed 命令实现这一点。提前谢谢
试试这个awk
:
awk -v RS= -v ORS='\n\n' '/^\[pqr\]/{sub(/para2=[^\n]*/, "para2=foobar")} 1' file
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=333
para2=foobar
para3=1345
[xyz]
para1=888
para2=236
para3=964
我通常使用类似这样的awk
命令:
$ awk '/^\[/{b=0} /^\[pqr\]/{b=1} /^para2=/{if(b) {sub(/=.*/, "=newvalue")}} 1' t
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=333
para2=newvalue
para3=1345
[xyz]
para1=888
para2=236
para3=964
这个想法是使用一个布尔变量(这里是b
),当我们进入正确的“块”时它被设置为 1,当你进入另一个块时它被设置回 0。
然后只需通过检查b
的值来验证您在后续操作中是否在正确的块中,在这种情况下替换 para2 的值。 我还使用这种技术从配置文件中简单地提取一个特定的“块”。
使用 perl:
#!/usr/bin/env perl
use strict;
use warnings;
#separate records with double line feed.
local $/ = "\n\n";
#iterate stdin or file names specified on command line
while ( <> ) {
#replace if the block starts [pqr]
s/para2=\d+/para2=9999/m if m/^\[pqr\]/;
print;
}
这个单行代码是;
perl -pe 'BEGIN { $/ = "\n\n" } s/para2=\d+/para2=9999/m if m/^\[pqr\]/;'
并给出(供您输入):
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=333
para2=9999
para3=1345
[xyz]
para1=888
para2=236
para3=964
awk -v RS= -v ORS='\n\n' '/pqr/{sub(/para2=765/,"para2=new")}1' file
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=333
para2=new
para3=1345
[xyz]
para1=888
para2=236
para3=964
我只会为此使用 Perl。 用于跟踪当前组的语句。 除了特定组之外,跳过修改的一个语句。 用新值替换 key= 之后的所有内容的语句。
perl -i -ple '$group = $1 if /^\[(.*?)\]/; next unless $group eq "pqr"; s/(?<=^para2=).*/newvalue/' file.conf
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.