【问题标题】:awk to find and output differences in filesawk 查找和输出文件中的差异
【发布时间】:2016-01-04 22:39:45
【问题描述】:

我试图找出file1.txtfile2.txt 之间的差异并输出差异。我试过diffsed 并且输出没有返回任何差异。我还尝试了awk 并在$2 上进行匹配,但我认为语法错误,因为文件被创建但它是 0kb。我使用的实际数据非常大,但我知道应该有 18 个差异。谢谢你:)。

awk 'NR==FNR{a[$2]++;next} !($2 in a){print $2}' file1.txt file2.txt > diff.txt

file1.txt

chr1    955542  955763
chr1    957570  957852
chr1    976034  976270

file2.txt

chr1    955542  955763  +   AGRN:exon.1
chr1    957570  957852  +   AGRN:exon.2
chr1    976034  976270  +   AGRN:exon.2;AGRN:exon.3;AGRN:exon.4
chr1    976542  976787  +   AGRN:exon.3;AGRN:exon.5
chr1    976847  977092  +   AGRN:exon.6

期望的输出

chr1    976542  976787  +   AGRN:exon.3;AGRN:exon.5
chr1    976847  977092  +   AGRN:exon.6

差异结果(因为这是两个文件中都不存在的两条记录)

1,52058c1,52040
< chr1  955542  955763
< chr1  957570  957852
< chr1  976034  976270

【问题讨论】:

  • 为什么diff file1.txt file2.txt 不工作?
  • 我试过了,返回的结果是文件中的所有内容,而不是差异。谢谢你:)。
  • 您期望有什么不同?根据您正在检查第二个字段的脚本,因此它们是匹配的,因此不会有任何差异。
  • @Chris - 不,我们不是在询问我们看不到的文件之间的差异。我们正在询问您发布的我们可以看到的文件之间有什么区别,以及这些文件的预期输出是什么。这就是我们必须继续进行的所有工作,也是我们要测试潜在解决方案的内容。如果这些文件不能代表您的真实输入并证明问题,请编辑您的问题以解决该问题。
  • 这有点,我想,但现在你只需将!($2 in a){print $2} 更改为!($2 in a){print $0}(习惯上只是!($2 in a)),你最初发布的脚本就可以工作,我如果这确实是您的问题,那么这对您来说肯定是显而易见的,所以我想到目前为止您还无法沟通肯定还有其他事情发生。

标签: awk


【解决方案1】:

我很好奇 diff 没有按你想要的那样工作,但你的 awk 逻辑不正确:

您只检查第二个字段(由空格分隔)的值。在您的示例中,第二个字段完全相同,因此没有打印任何内容。使用整行代替按预期工作:

在所有不同的地方使用您的示例文本:

$ cat file1.txt
chr1 955542 955763
chr1 957570 957852
chr1 976034 976270

$ cat file2.txt
chr1 955542 955763 + AGRN:exon.1
chr1 957570 957852 + AGRN:exon.2
chr1 976034 976270 + AGRN:exon.2;AGRN:exon.3;AGRN:exon.4

$ awk 'NR==FNR{a[$0]++;next} !($0 in a){print $0}' file1.txt file2.txt > diff.txt

$ cat diff.txt
chr1 955542 955763 + AGRN:exon.1
chr1 957570 957852 + AGRN:exon.2
chr1 976034 976270 + AGRN:exon.2;AGRN:exon.3;AGRN:exon.4

这里与第二行相同,只是为了显示它以更明显的方式工作。

$ cat file1.txt
chr1  955542 955763
chr1  957570 957852
chr1  976034 976270

$ cat file2.txt
chr1 955542 955763 + AGRN:exon.1
chr1 957570 957852
chr1 976034 976270 + AGRN:exon.2;AGRN:exon.3;AGRN:exon.4

$ awk 'NR==FNR{a[$0]++;next} !($0 in a){print $0}' file1.txt file2.txt > diff.txt

$ cat diff.txt
chr1 955542 955763 + AGRN:exon.1
chr1 976034 976270 + AGRN:exon.2;AGRN:exon.3;AGRN:exon.4

编辑

根据评论指出: “52,000 行中应该有 18 个差异。File1.txt 有 52,058 个条目,而 file2.txt 中有 52,040 个条目。我想找出这 18 个是什么”

鉴于您说 file1 有更多行,您需要先处理 file2。读取的第一个文件填充数组,然后第二个文件检查该数组中存在的行。您需要先处理较小的文件,以便您感兴趣的其他行不在数组中。和上面的逻辑一样,只是文件顺序切换了,例如:

$ cat file1.txt
chr1 955542 955763
chr1 957570 957852
chr1 976034 976270
New Line!
Not in file2!

$ cat file2.txt
chr1 955542 955763 + AGRN:exon.1
chr1 957570 957852
chr1 976034 976270 + AGRN:exon.2;AGRN:exon.3;AGRN:exon.4

$ awk 'NR==FNR{a[$0]++;next} !($0 in a){print $0}' file2.txt file1.txt > diff.txt

$ cat diff.txt
chr1 955542 955763
chr1 976034 976270
New Line!
Not in file2!

$ awk 'NR==FNR{a[$0]++;next} !($0 in a){print $0}' file1.txt file2.txt > diff.txt

$ cat diff.txt
chr1 955542 955763 + AGRN:exon.1
chr1 976034 976270 + AGRN:exon.2;AGRN:exon.3;AGRN:exon.4

请注意,首先读取 file1 不会发出额外的行。

如果您不关心行上的附加文本,只关心第二个字段中的文本,那么您可以像原来一样使用 $2。

【讨论】:

    【解决方案2】:
    $ awk 'NR==FNR{a[$2];next} !($2 in a)' file1 file2
    chr1    976542  976787  +   AGRN:exon.3;AGRN:exon.5
    chr1    976847  977092  +   AGRN:exon.6
    

    【讨论】:

      猜你喜欢
      • 2021-07-01
      • 1970-01-01
      • 2011-10-05
      • 2014-06-20
      • 2022-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多