【问题标题】:AWK: 2 columns 2 files display where second column has unique dataAWK:显示 2 列 2 个文件,其中第二列具有唯一数据
【发布时间】:2019-05-14 06:40:59
【问题描述】:

我需要第一列来检查它是否与第二个文件的第一列不匹配。但是,如果第二列与第二个文件的第二列匹配,则在 Linux 上使用 awk 显示此数据。

我希望 awk 检测第一个文件的第一列和第二列与第二个文件的更改。

file1.txt
sdsdjs ./file.txt
sdsksp ./example.txt
jsdjsk ./number.txt
dfkdfk ./ok.txt

file2.txt
sdsdks ./file.txt <-- different
sdsksd ./example.txt   <-- different
jsdjsk ./number.txt <-- same
dfkdfa ./ok.txt <-- different

Expected output:
sdsdks ./file.txt
sdsksd ./example.txt
dfkdfa ./ok.txt

请注意第二个文件中可能缺少行并且与第一个不同。

如上所见,awk如何只在第二列唯一且与第一列不匹配的情况下显示结果?

【问题讨论】:

  • 您能否详细说明您的意思:注意第二个文件中可能缺少行并且与第一个不同。因为两个文件包含完全相同行数。

标签: awk


【解决方案1】:

这样的事情可能对你有用:

awk 'FNR == NR { f[FNR"_"$2] = $1; next }
     f[FNR"_"$2] && f[FNR"_"$2] != $1' file1.txt file2.txt

细分:

FNR == NR {                        } # Run on first file as FNR is record number for the file, while NR is the global record number
            f[FNR"_"$2] = $1;        # Store first column under the name of  FNR followed by an underbar followed by the second column 
                              next   # read next record and redo
f[FNR"_"$2] && f[FNR"_"$2] != $1     # If the first column doesn't match while the second does, then print the line

忽略第二列的更简单方法是:

awk 'FNR == NR { f[FNR"_"$1] = 1; next }
     !f[FNR"_"$1]' file1.txt file2.txt

【讨论】:

  • @Dave 只需从解决方案中删除 { print $2 }
【解决方案2】:

如果记录不必位于文件中的相应位置,即。我们比较匹配的第二列字符串,这应该足够了:

$ awk '{if($2 in a){if($1!=a[$2])print $2}else a[$2]=$1}' file1 file2

输出:

file.txt

印刷精美:

$ awk '{
    if($2 in a) {           # if $2 match processing
        if($1!=a[$2])       # and $1 don t
            print $2        # output
    } else                  # else
        a[$2]=$1            # store
}' file1 file2

更新

$ awk '{if($2 in a){if($1!=a[$2])print $1,$2}else a[$2]=$1}'  file1 file2
sdsdks ./file.txt
sdsksd ./example.txt
dfkdfa ./ok.txt

基本上把print $2改成了print $1,$2

【讨论】:

  • 第一列和第二列结合使用,比较前一个文件的内容...
【解决方案3】:

您的问题的措辞非常令人困惑,但是在阅读了几次并查看了您发布的预期输出后,我认为您只是想说您想要 file2 中没有出现在 file1 中的行。如果是这样,那就是:

$ awk 'NR==FNR{a[$0];next} !($0 in a)' file1 file2
sdsdks ./file.txt
sdsksd ./example.txt
dfkdfa ./ok.txt

如果您的真实数据包含的字段多于示例输入中显示的字段,但您只希望前 2 个字段用于比较,则修复您的问题以显示更具代表性的示例,但解决方案是:

$ awk 'NR==FNR{a[$1,$2];next} !(($1,$2) in a)' file1 file2
sdsdks ./file.txt
sdsksd ./example.txt
dfkdfa ./ok.txt

如果不是这样,那么请编辑您的问题以阐明您正在尝试做什么,并包含一个示例,其中上述内容没有产生预期的输出。

【讨论】:

    【解决方案4】:

    我是这样理解原来的问题的:

    • file1file2 这两个文件包含一组 键值 对。
    • key是文件名,value是第一列的字符串
    • 如果在file1file2 之间找到匹配的key,但value 不同,则打印file2 的匹配行

    您并不需要高级 awk 来完成这项任务,它可以通过简单的 awk 和 grep 管道轻松实现。

    $ awk '{print $NF}' file2.txt | grep -wFf - file1.txt | grep -vwFf - file2.txt
    sdsdks ./file.txt
    sdsksd ./example.txt
    dfkdfa ./ok.txt
    

    在这里,第一个 grep 将从file1.txt 中选择具有相同键(文件名)的行。第二个 grep 将尝试在 file2 中搜索来自 file1 的完整匹配行,但它会打印失败。请注意,在这种情况下,行需要完全相同。

    如果你只是想用awk,那么上面的逻辑是用Ed Morton提出的方案来实现的。此处无需赘述。

    【讨论】:

      【解决方案5】:

      我想这就是你要找的东西

      $ awk 'NR==FNR{a[$2]=$1; next} a[$2]!=$1' file1 file2
      
      sdsdks ./file.txt
      sdsksd ./example.txt  
      dfkdfa ./ok.txt
      

      打印来自 file2 的记录,其中 field1 值对于相同的 field2 值是不同的。此脚本假定 field2 值在每个文件中是唯一的,因此可以将其用作键。由于内容看起来像文件路径,这是一个有效的假设。否则,您可能需要将记录与相应的行号进行匹配。

      【讨论】:

        【解决方案6】:

        如果您正在寻找基于行上第一个字段不同的更直接的基于行的差异。

        awk 'NR==FNR { a[NR] = $1; next } a[FNR]!=$1' file1 file2
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-10-20
          • 2019-09-08
          • 2021-10-07
          • 2016-09-22
          • 1970-01-01
          • 2014-05-24
          • 2012-04-01
          相关资源
          最近更新 更多