【问题标题】:Use awk to extract value from a line使用 awk 从一行中提取值
【发布时间】:2014-08-08 02:42:41
【问题描述】:

我在一个文件中有这两行:

<first-value system-property="unique.setting.limit">3</first-value>
<second-value-limit>50000</second-value-limit>

我想使用 awk 或 sed 将以下内容作为输出:

3    
50000

使用这个 sed 命令没有像我希望的那样工作,我怀疑这是由于我的行条目中存在引号和分隔符。

sed -n '/WORD1/,/WORD2/p' /path/to/file

如何从文件中提取我想要的值?

【问题讨论】:

    标签: bash awk sed


    【解决方案1】:
    awk -F'[<>]' '{print $3}' input.txt
    

    输入.txt:

    <first-value system-property="unique.setting.limit">3</first-value>
    <second-value-limit>50000</second-value-limit>
    

    输出:

    3
    50000
    

    【讨论】:

    • 酷,我不知道我可以设置多个字段分隔符。
    • @martin 更一般的,你可以使用Regular Expressions
    【解决方案2】:
            sed -e 's/[a-zA-Z.<\/>= \-]//g' file
    

    【讨论】:

    • 如果&lt; ... &gt; 标签中有数字,则此解决方案不适合,因为它将保留它们并将它们连接到 OP 要提取的实际数字。
    【解决方案3】:

    使用sed

    sed -E 's/.*limit"*>([0-9]+)<.*/\1/' file
    


    说明:
    .* 处理字符串 limit

    之前的所有内容

    limit"* 处理两条线路,一条使用limit",另一条使用limit

    ([0-9]+) 负责匹配号码,并且只处理您要求中所述的号码。

    \1 实际上是捕获模式的快捷方式。当模式将其全部或部分内容分组到一对括号中时,它会捕获内容并将其临时存储在内存中。更多详情请参考https://www.inkling.com/read/introducing-regular-expressions-michael-fitzgerald-1st/chapter-4/capturing-groups-and

    【讨论】:

    • 很多人写sed -E的意思是--extended-regexp。这是 grep 的正确短选项,但不适用于 sed。在 sed 中(至少在 GNU sed 中),--regexp-extended 的正确缩写形式是 -r。 POSIX 规范 specifies -E for grep,但 nothing for sedsed 的手册页清楚地指出了-r,没有提到-B。此外,您建议的解决方案(这里有很多)不适用于十进制数。
    【解决方案4】:

    带参数扩展的脚本解决方案:

    #!/bin/bash
    
    while read line || test -n "$line" ; do
        value="${line%<*}"
        printf "%s\n" "${value##*\>}"
    done <"$1"
    

    输出:

    $ ./ltags.sh dat/ltags.txt
    3
    50000
    

    【讨论】:

      【解决方案5】:

      在我看来像 XML,所以假设它是某些有效 XML 的一部分,例如

      <root>
      <first-value system-property="unique.setting.limit">3</first-value>
      <second-value-limit>50000</second-value-limit>
      </root>
      

      您可以使用 Perl 的 XML::Simple 并执行以下操作:

      perl -MXML::Simple -E '$xml = XMLin("file"); say $xml->{"first-value"}->{"content"}; say $xml->{"second-value-limit"}'
      

      输出:

      3
      50000
      

      如果 XML 结构更复杂,那么您可能需要更深入地挖掘以获得所需的值。如果是这种情况,您应该编辑问题以显示更大的图景。

      【讨论】:

        【解决方案6】:

        Ashkan 的 awk 解决方案很简单,但让我建议一个接受非整数的 sed 解决方案:

        sed -n 's/[^>]*>\([.[:digit:]]*\)<.*/\1/p' input.txt
        

        这会提取该行的第一个 &gt; 字符和后面的 &lt; 之间的数字。在我的 RE 中,这个“数字”可以是空字符串,如果您不想接受空字符串,请将 -r 选项添加到 sed 并将 \([.[:digit:]]*\) 替换为 ([.[:digit:]]+)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-10
          • 2013-05-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多