【问题标题】:linux|awk|shell script modification of line with same name in many blockslinux|awk|shell脚本修改多块同名行
【发布时间】:2016-01-19 07:49:09
【问题描述】:
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 命令实现这一点。提前致谢

【问题讨论】:

标签: linux bash perl awk sed


【解决方案1】:

试试这个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

【讨论】:

  • 嗨 Anubhava,PFB 命令的输出 bash-2.03$ awk -v RS= -v ORS='\n\n' '/^[pqr]/{sub(/para2=[ ^\n]*/, "para2=foobar")} 1' tmp.ini awk:第 1 行附近的语法错误 awk:在第 1 行附近退出
  • 你的 awk 版本是多少?
【解决方案2】:

我通常使用类似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 的值。我还使用这种技术从配置文件中简单地提取一个特定的“块”。

【讨论】:

  • 嗨 Seco,bash-2.03$ awk '/^[/{b=0} /^[pqr]/{b=1} /^para2=/{if(b) {sub( /=.*/, "=newvalue")}} 1' tmp.ini awk:第 1 行附近的语法错误 awk:第 1 行附近的非法语句 awk:第 1 行附近的语法错误 awk:在第 1 行附近退出 这是错误我正进入(状态。请指教
  • 您需要确保使用反斜杠正确转义方括号,例如/^[ 而不是你粘贴的 /^[
【解决方案3】:

我只会为此使用 Perl。一个跟踪当前组的语句。一个语句跳过除特定组之外的修改。用新值替换 key= 之后的所有内容的语句。

perl -i -ple '$group = $1 if /^\[(.*?)\]/; next unless $group eq "pqr"; s/(?<=^para2=).*/newvalue/' file.conf

【讨论】:

    【解决方案4】:

    使用 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 
    

    【讨论】:

    • 嗨 Sobrique,我收到语法错误。请查看下面的输出... bash-2.03$ perl -pe 's/BEGIN { $/ = "\n\n" } para2=\d+/para2=9999/m if m/^[pqr]/;' tmp.ini Bareword 在 -e 第 1 行,"s/BEGIN { $/ = "\n\n" } para2=\d+/para2" 附近的 -e 第 1 行,"s/BEGIN" 附近找到运算符预期的位置{ $/ = "\n\n" } para2=\d+/para2" 搜索模式未在 -e 第 1 行终止。
    • 由于某种原因,我在粘贴时丢失了部分文本。已编辑:perl -pe 'BEGIN { $/ = "\n\n" } s/para2=\d+/para2=9999/m if m/^\[pqr\]/;'`
    【解决方案5】:
    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    
    

    【讨论】:

      猜你喜欢
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      • 2017-07-05
      • 2014-03-26
      • 2018-08-12
      相关资源
      最近更新 更多