【问题标题】:awk same start and end patternawk 相同的开始和结束模式
【发布时间】:2013-10-21 03:25:53
【问题描述】:

我有一个如下所示的模式。我正在尝试提取多行记录(从 Dr Group Name 到第一个空白行)。我试过了:

awk 'BEGIN{RS="\n" } /DR Group Name: \\Data Replication\\mc_wtec_1/,/\n/'

但它让我获得了所有四条记录。

Storage WWN: 50001FE15007DBA0
    DR Group Name: \Data Replication\mc_wtec_1
        WWID list:
                   600508B4001078FD0002400001800000

    DR Group Name: \Data Replication\vanilla_dr
        WWID list:
                   600508B4001078F10002400002D20000


Storage WWN: 50001FE15007DBD0
    DR Group Name: \Data Replication\mc_wtec_1
        WWID list:
                   600508B4001078FD0002400001800000

    DR Group Name: \Data Replication\vanilla_dr
        WWID list:
                   600508B4001078F10002400002D20000

【问题讨论】:

    标签: regex bash awk


    【解决方案1】:
    awk '/wtec_1/ {ok=1} /^$/ {ok=0} {if(ok){print $0}}' filename
    

    按照您的要求做。基于样本。

    【讨论】:

      【解决方案2】:

      看起来您只需要删除“Storage WWN”行,然后您将获得每条记录:

      < input sed '/^Storage WWN/d' | awk '{ print "Record: ", $0 }' RS=
      

      例如获取第三条记录:

      < input sed '/^Storage WWN/d' | awk NR==3 RS=
      

      要获得 mc_wtec_1,请尝试:

      < input sed '/^Storage WWN/d' | awk '/mc_wtec_1/' RS=
      

      (在上述所有内容中,假设您的输入数据位于名为 'input' 的文件中。该文件可以指定为sed 的参数,而不是由 shell 重定向,并在 ' 之前执行重定向sed' 不是必需的。)

      【讨论】:

      • 我不禁觉得同时使用awksed 有点笨拙,而单独使用awk 就足够了。
      • @Jonathan,我同意,但我看不到删除单个行以及重新分配 RS 的好方法。这看起来很老套,但可以接受。
      【解决方案3】:

      搜索模式并在其后打印两行:

      awk '/ DR Group Name: \Data Replication\mc_wtec_1/{print;for(i=1;i<=3;i++){getline;print}}' filename
      

      或者更好的方法

      在脚本中添加正则表达式搜索模式

      awk '/ DR Group Name: \\Data Replication\\mc_wtec_1/,/([A-Z]+[0-9]+)/' filename
      

      ([A-Z]+[0-9]+) 将寻找 600508B4001078FD0002400001800000 模式

      输出:

      DR Group Name: \Data Replication\mc_wtec_1
          WWID list:
                     600508B4001078FD0002400001800000
      
      DR Group Name: \Data Replication\mc_wtec_1
          WWID list:
                     600508B4001078FD000240000180000000
      

      【讨论】:

      • 这适用于示例数据,但有空间认为 WWID list 可能包含多行数据(否则,它不是一个列表),此时这变得脆弱。规范说记录的结尾用空行标记;一个好的解决方案将使用它而不是行数。
      • @JonathanLeffler,是的,谢谢,这是真的,添加了其他替代方案
      【解决方案4】:

      RS="\n" 部分是奇数;这不是默认的记录分隔符吗?删除它对匹配的输出没有影响,我不希望它这样做。

      结束模式也是假的。您正在搜索包含换行符的行,但 awk 会从输入行中删除换行符,因此它不匹配任何内容,因此模式范围从第一行 DR Group Name 延伸到文件末尾。

      你想寻找一个空行;那是/^$/。因此:

      $ awk '/DR Group Name: \\Data Replication\\mc_wtec_1/,/^$/' data
          DR Group Name: \Data Replication\mc_wtec_1
              WWID list:
                         600508B4001078FD0002400001800000
      
          DR Group Name: \Data Replication\mc_wtec_1
              WWID list:
                         600508B4001078FD0002400001800000
      $
      

      【讨论】:

      • 空行搜索是个好办法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-30
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 2013-05-25
      相关资源
      最近更新 更多