【问题标题】:How to compare two files containing numbers in UNIX?如何在 UNIX 中比较两个包含数字的文件?
【发布时间】:2015-03-18 13:42:12
【问题描述】:

我有两个文件。第一个文件包含 500000 条记录(数字),第二个文件包含 4000000 条记录(数字)。

数字不在一行中。它们像 Excel 工作表中的一列一样。

文件 1 包含以下数字:

1483
2111
2973
3214
3503
3639
3747
4042
4351
4766
4809
5950
6616
6899
7559
7940
8205
8262
8291 

文件 2 包含以下数字:

1483
2111
2973
3214
3503
3639
3747
4042
4351
4766
4809
5950
6616
6899
7559
7940
8205
8262
8291
9000
9163
9229
9497
9719
0409
0421
0698
0924
1059

我想找出第一个文件中有多少记录不存在于包含第二个文件的记录中。我尝试使用 Excel 进行比较,但我的笔记本电脑多次进入挂起状态。另外,我在 UNIX 中尝试使用 diff 命令,但没有达到预期的输出。 请有人帮我在 UNIX 中解决这个问题,因为它比其他方法花费的时间更少。

【问题讨论】:

  • 要获得一个好的答案,如果您提供数据样本和您期望的输出示例,将会很有用。如果只是一长串数字,是否已排序?
  • Hi Sobrique,File 1 contains below numbers:1483 2111 2973 3214 3503 3639 3747 4042 4351 4766 4809 5950 6616 6899 7559 7940 8205 8262 8291 File 2 contains below numbers:1483 2111 2973 3214 3503 3639 3747 4042 4351 4766 4809 5950 6616 6899 7559 7940 8205 8262 8291 9000 9163 9229 9497 9719 0409 0421 0698 0924 1059。
  • 你能把这些编辑成你的问题吗?看起来像纯数字,按顺序排序。这让问题变得容易多了。
  • 数字不在一行中。它们像excel表格的一列一样,是一个接一个
  • 好的。这就是为什么将输入数据作为样本包含在内很重要的原因。与文件中的外观完全相同(包括换行符)。 diff 在那种情况下会做你想做的事。

标签: unix compare diff


【解决方案1】:

file 2中的数据没有完全排序;有一些数字以 0 和 1 开头。因此,您确实需要对数字进行排序,然后您可以将 comm 与 Bash(Korn shell、Z Shell)和 process substitution 一起使用:

comm <(sort file.1) <(sort file.2)

这将打印仅在第 1 列中出现在 file.1 中的数字,仅在第 2 列中出现在 file.2 中的数字(由制表符缩进),以及在第 3 列中出现的数字(由两个制表符缩进) .

您可以使用 -23 选项隐藏第 2 列和第 3 列,只留下 file.1 中的数字:

comm -23 <(sort file.1) <(sort file.2)

如果你想计算有多少这样的数字,那么:

comm -23 <(sort file.1) <(sort file.2) | wc -l

如果您没有进程替换,那么您需要分别对这两个文件进行排序。如果您不再需要原始顺序的原始文件,则可以使用:

sort -o file.1 file.1
sort -o file.2 file.2
comm -23 file.1 file.2 | wc -l

替代品很多。

【讨论】:

    【解决方案2】:

    Awk 也可能提供一些选项来解决这个问题。这是一个。

    此解决方案没有运行 comm 解决方案所需的大量 sort 函数和 bash 进程替换的开销...尽管它确实要求您的系统足够强大以加载所有将较大的文件放入内存中进行处理。

    $ awk -f '
    
      # populate an array with the contents of the first file only...
      NR==FNR { a[$1]; next; }
    
      # then delete any array elements that are in the second file...
      { delete a[$1]; }
    
      # finally, display our results.
      END {
        for (i in a) count++;
        printf("Count: %d entries\n", count);
        for (i in a) printf("%s\n", a[i]);
      }
    
      ' file2 file1
    

    这里的想法是,我们将逐步遍历file2(较长的文件)并将其放入一个数组中,然后我们从该数组中删除出现在file(较短的文件)中的所有内容,然后计数并打印剩下的。

    附带条件 #1:如上所述,这要求您有可用内存来将所有 file2 存储在内存中的数组中。您必须自己确定这是否可行。 (也许可以尝试一下!)

    附带条件 #2:我没有对此进行测试,即使是语法错误也是如此。 YMMV。 :)

    【讨论】:

      猜你喜欢
      • 2022-11-12
      • 2016-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多