【问题标题】:selectively extracting fields from a delimited file through the terminal通过终端选择性地从分隔文件中提取字段
【发布时间】:2013-01-30 10:57:02
【问题描述】:

如果我有一个分隔文件,例如;

A=1|B=2|C=3|D=4|E=5|F=6

我想提取某些字段并仅使用标准 unix 工具(即 grep、awk、cut)将它们打印在一行上。我怎么能这样做?

文本字段的顺序可能并不总是相同,并且一行上的内容可能比另一行上的多。我希望能够根据它们的开头来选择字段。

因此,对上述 A= 和 C= 的查询应将以下内容作为单行输出;

A=1 C=2

谢谢!

【问题讨论】:

    标签: linux bash unix awk grep


    【解决方案1】:

    我建议使用支持将 RS 指定为正则表达式的 awk 版本,例如gawk 或 mawk:

    echo 'A=1|B=2|C=3|D=4|E=5|F=6' | 
      awk -v RS='[|\n]' -v ORS=' ' -v pat='(A|C)=' '$0 ~ pat'; echo
    

    或者如果你想避免最后的回声:

    echo 'A=1|B=2|C=3|D=4|E=5|F=6' | 
      awk -v RS='[|\n]' -v ORS=' ' -v pat='(A|C)=' '$0 ~ pat; END { printf "\n" }'
    

    我最喜欢的:

    echo 'A=1|B=2|C=3|D=4|E=5|F=6' | 
      awk '$0 ~ pat' RS='[|\n]' ORS=' ' pat='(A|C)='; echo 
    

    输出:

    A=1 C=3
    

    编辑

    错误修正,换行符也应该被视为记录分隔符。

    【讨论】:

    • 谢谢,这正是我所需要的。
    • @user1977952 用pat='(A|F)=' 试试看它是否仍然符合您的要求,因为在这种情况下它会添加一个空行。在 $0 测试前添加 {sub(/\n/,"")} 或在其后添加 {sub(/\n/,"");print}
    • @EdMorton:我明白你的意思,我已经更新了使用正则表达式 RS 的答案,将解决方案限制为 gawk 或 mawk(可能是其他 awk 版本?)。
    【解决方案2】:

    这符合您的需要吗?

    kent$  echo "A=1|B=2|C=3|D=4|E=5|F=6"|grep -Po "(?<=\||^)(A=|C=)[^|]*"
    A=1
    C=3
    

    如果你想在单行中使用,请将其通过管道发送到 tr '\n' ' '

    【讨论】:

    • 嗨,很遗憾,它并没有 100% 满足我的需求,因为它会将整个输出打印在一行上。还是谢谢!
    • @user1977952 你希望它在一行中打印,不是吗?
    【解决方案3】:

    你也可以使用这个:

    awk -F"|" '{for(i=1;i<=NF;i++){if($i~/[A|C]\=/)printf $i" "}}'
    

    你也可以使用 perl:

    perl -lne 'push @a,/[A|C]=\d+/g;END{print "@a"}'
    

    【讨论】:

      【解决方案4】:

      使用 sed

      sed -re 's/(A=[0-9]+)(.*)(C=[0-9]+)(.*)/\1 \3/' temp.txt

      输出

      A=1 C=3

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-15
        • 1970-01-01
        相关资源
        最近更新 更多