【问题标题】:Increase version number by one in next line using awk使用 awk 在下一行将版本号加一
【发布时间】:2018-11-04 07:01:48
【问题描述】:

我需要使用 awk 在唯一字符串之后的行中将版本号加一。

原文:

<key>UniqueKey</key>
<string>100</string>

期望的输出

<key>UniqueKey</key>
<string>101</string>

不幸的是“string”在文件中不是唯一的,所以我必须修改唯一的“key”字符串后面的行。我需要取这个数字,不管它是什么,然后加一。该命令将在每次都会被删除的虚拟工作空间中运行,因此最好使用简单的 awk 命令。

【问题讨论】:

    标签: awk


    【解决方案1】:
    $ awk -F'[<>]' '$3=="UniqueKey"{n=NR} 
       n && NR==n+1 && $2=="string"{sub($3,$3+1)}1' file
    
    <key>UniqueKey</key>
    <string>101</string>
    

    【讨论】:

      【解决方案2】:

      这看起来非常像一个 XML 文件。强烈建议使用与 XML 相关的工具来完成这项工作,例如 xmlstarlet

      假设给定的输入文件格式为:

      <header>
        <node>
          <key>UniqueKey</key>
          <foo />
          <string>100</string>
        </node>
        <node>
          <key>UniqueKey</key>
          <string>101</string>
          <string>200</string>
        </node>
      </header>
      

      然后以下命令将根据要求更新:

      $ xmlstarlet ed -u '//key[text()="UniqueKey"]/following-sibling::string[1]' \
                      -x '(text()+1)' file.xml
      

      执行以下操作:

      • ed:进入编辑模式
      • -u &lt;xpath&gt;:更新xpath匹配的节点

        • //key:选择名称为key的任何节点
        • //key[text()="UniqueKey"]:选择名称为key 且值为"UniqueKey" 的任何节点
        • //key[text()="UniqueKey"]/following-sibling::string:选择key 的第一个“字符串”兄弟姐妹key
      • -x '(text()+1)':通过表达式text()+1更新选定节点值

      然后输出由 :

      <?xml version="1.0"?>
      <header>
        <node>
          <key>UniqueKey</key>
          <foo/>
          <string>101</string>   # change
        </node>
        <node>
          <key>UniqueKey</key>
          <string>102</string>   # change
          <string>200</string>   # no change
        </node>
      </header>
      

      或者如果它真的必须是下一个节点,那么你需要使用concatsubstring 玩一个技巧,因为 xpath-1.0 没有 if 条件。更多详情here

      $ xmlstarlet ed -u '//key[text()="UniqueKey"]/following-sibling::*[1]' \
                      -x 'substring(text()+1,1,number(name()="string")*string-length(text()+1))' file.xml
      
      <?xml version="1.0"?>
      <header>
        <node>
          <key>UniqueKey</key>
          <foo/>
          <string>100</string>   # no change
        </node>
        <node>
          <key>UniqueKey</key>
          <string>102</string>   # change
          <string>200</string>   # no change
        </node>
      </header>
      

      【讨论】:

        【解决方案3】:
        $ awk -F'[<>]' '$2=="string" && p3=="UniqueKey" { sub(/>[^<]+/,">"$3+1) } {p3=$3} 1' file
        <key>UniqueKey</key>
        <string>101</string>
        

        【讨论】:

        • 虽然这个答案可能是正确且有用的,但最好在其中附上一些解释来解释它如何帮助解决问题。如果有更改(可能不相关)导致它停止工作并且用户需要了解它曾经是如何工作的,这在未来变得特别有用。
        • 你错了。任何人只要简单浏览一下 google 和/d/或手册页就可以解决的琐碎解决方案最好保持原样,因为人们从中学到的不仅仅是一个脚本的工作原理。
        • 嗨,埃德。显然你的业力比我多得多,所以我会推迟。我将其保留在仅代码答案上,以鼓励更丰富的答案。对我们有经验的人来说微不足道的事情对刚开始的人来说可能并不重要:)
        • 不要在您不理解的仅代码答案上发布 cmets,这只会使网站混乱并浪费人们的时间。该工具在看到纯代码答案时会标记可能低质量答案,这是一种有很大缺陷的方法,由了解代码的人来决定答案是否低质量 - 从根本上说没有错误的代码答案和代码并不意味着低质量。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-20
        • 2014-07-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-26
        相关资源
        最近更新 更多