【问题标题】:AWK - reading columns from two filesAWK - 从两个文件中读取列
【发布时间】:2015-03-28 22:54:57
【问题描述】:

)。需要你的帮助。我有两个 shell 脚本,它们产生如下输出

脚本 1 输出 (abc.txt) -->

application_name      Status
abc                   Available
def                   NotAvailable
xyz                   Available

脚本 2 输出 (def.txt)-->

application_name      Status
abc                   NotAvailable
def                   Available
xyz                   Available

如您所见,两个文件中的应用程序名称顺序相同,但状态不同,例如在一个文件中,应用程序 abc 的状态可用,而在另一个文件中则不可用。我必须编写一个 awk 脚本来输出第三个文件,其中包含每个应用程序的最终状态。例如如果文件 abc.txt 中应用程序 abc 的状态为“available”,而文件 def.txt 中为 NotAvailable,则应用程序的状态应为“NotAvailable”。请在下面的示例输出文件中找到 -

最终输出文件 (xyx.txt)

application_name     status
abc                  NotAvailable
def                  NotAvailable
xyz                  Available (since the status of this application is "available" in both the input file).

我尝试使用以下命令执行此操作,但它不起作用。它给出了错误的输出

awk 'NR==FNR {f1[$1]=$0; next} $1 in f1 && $0 != f1[$1] || $0 == f1[$1]' abc.txt def.txt

【问题讨论】:

    标签: awk


    【解决方案1】:

    总之,一个应用程序只有在两个文件中都可用时才是Available。在这种情况下:

    $ awk 'NR==FNR {if ($2=="NotAvailable")f1[$1]=$0; next} $1 in f1 {print f1[$1];next} 1' abc.txt def.txt
    application_name      Status
    abc                   NotAvailable
    def                   NotAvailable
    xyz                   Available
    

    工作原理

    总结规则:

    1. 如果应用程序在第一个文件中为 NotAvailable,则无论第二个文件中的内容如何,​​其最终状态都是 NotAvailable。

    2. 如果应用程序在第一个文件中可用,则其最终状态与第二个文件中的状态相同。

    以下代码实现了这些规则:

    • NR==FNR {if ($2=="NotAvailable")f1[$1]=$0; next}

      浏览第一个文件时,保存所有 NotAvailable 应用程序的状态。

    • $1 in f1 {print f1[$1];next}

      如果应用程序在第一个文件中为 NotAvailable,则从第一个文件 (NotAvailable) 打印其状态。

    • 1

      否则,从第二个文件打印状态。 (1 是 awk 用于打印当前行的神秘简写。)

    【讨论】:

      【解决方案2】:
      $ awk 'NR==FNR{s[$1]=$0;next} $2=="Available"{$0=s[$1]} 1' file1 file2
      application_name      Status
      abc                   NotAvailable
      def                   NotAvailable
      xyz                   Available
      

      【讨论】:

        【解决方案3】:

        以前的答案很好,我不会加我关于awk 的两分钱。但是为了站在 Unix 哲学上,你可能会被join 工具所吸引。它将预装在任何 Linux 发行版上;只需输入:

        join f1.txt f2.txt
        

        结束看看会发生什么;然后,您可以轻松地将输出传递到您自己的awksed 命令(并在查看man join 之后调整连接行为)。

        最好的问候。

        【讨论】:

        • 我实际上说我的答案不是一个完整的答案,而是一个提示。我同意(我再说一遍)需要做更多的后期处理。但是原始发布者可能对这个非常接近他/她需要的命令感兴趣;如果文件间距不是主要要求,则可以通过管道传输两个简短易读的命令来构建一个优雅的解决方案。
        • 我同意这种观点,但您在这种特定情况下是错误的。 Join 并不接近 OP 的需求,并且使用 join(或 cat 或 paste 或其他任何东西作为第一阶段来组合输入文件)将不允许您创建更简洁、更优雅或以任何其他方式更好的解决方案而不是使用简单地对 2 个原始文件进行操作的单个命令。当然,可能有一些我没有想到的事情,所以如果您愿意编辑您的问题以显示您的想法......?
        • 感谢大家的帮助...我得到了答案..我将不得不多学习一点 AWK 技巧 :-)
        猜你喜欢
        • 2013-02-08
        • 1970-01-01
        • 2013-10-15
        • 1970-01-01
        • 2023-04-07
        • 2014-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多