【问题标题】:Find rows with the same value in a column in two files在两个文件的列中查找具有相同值的行
【发布时间】:2018-05-07 18:08:58
【问题描述】:

我有两个文件(数百万列)

File1.txt,~4k 行

some_key1 some_text1
some_key2 some_text2
...
some_keyn some_textn

File2.txt,约 20 M 行

some_key11 some_key11 some_text1
some_key22 some_key22 some_text2
...
some_keynn some_keynn some_textn

File1.txt 中的第 2 列和File2.txt 中的第 3 列完全匹配时,我想从两个文件中打印出特定的行。

编辑

这个我试过了(我忘了写),但它不起作用

awk 'NR{a[$2]}==FNR{b[$3]}'$1 in a{print $1}' file1.txt file2.txt

【问题讨论】:

  • 到目前为止你做了什么?
  • 我已经编辑了这个问题。我忘了添加我的尝试。 @JoaoVitorino
  • 请更具体地说明什么匹配什么。只有一列应该匹配吗?为什么这些文件有相同的名称?
  • @liborm 可以是多行与同一列。同名文件是错别字。
  • 你说你试过awk 'NR{a[$2]}==FNR{b[$3]}'$1 in a{print $1}' ,其中有3个单引号:awk 'NR...}'$1...}'。显然,您不能在由该字符分隔的字符串或脚本中间有一个 [未转义] 字符,所以 - 您希望中间的单引号是什么意思?你所拥有的就像写一个像He said "here is"the answer" to me这样的英文句子。在"-delimited 语句中间使用" 是没有意义的,对于任何给定字符都是如此,那么您对' 中间脚本的意图是什么?

标签: linux bash awk


【解决方案1】:

假设您的数据集在两个维度(行和列)上都很大。然后你想使用join。要使用join,您必须先对数据进行排序。类似的东西:

<File1.txt sort -k2,2 > File1-sorted.txt
<File2.txt sort -k3,3 -S1G > File2-sorted.txt

join -1 2 -2 3 File1-sorted.txt File2-sorted.txt > matches.txt

sort -k2,2 的意思是'对整行进行排序,使第二列的值按升序排列。 join -1 2 表示“第一个文件中的键是第二列”。

如果您的文件大于 100 MB,则可以通过 -S 选项为 sort 分配额外的内存。经验法则是分配输入大小的 1.3 倍以避免sort 进行任何磁盘交换。但前提是您的系统可以处理。


如果您的一个数据文件非常小(比如最多 100 行),您可以考虑执行类似的操作

<File2.txt fgrep -F <( <File1.txt cut -f2 ) > File2-matches.txt

要避免sort,但是您必须从该文件中查找“密钥”。

使用哪一个的决定与数据库世界中的“散列连接”和“合并连接”非常相似。

【讨论】:

  • join: File1-sorted.txt:3: is not sorted: 00000001 9D1DD657B7ED0FFA...不知道什么意思
  • 意思是它所说的;) 输入文件必须在您用作连接键的列上进行排序。我想在您的数据中它不会是第二列和第三列,因此您需要相应地更改 -k2,2-1 2 部分。并注意分隔符 - 如果您的字段中有空格,您需要使用例如\t。 (而且 - 我刚刚修正了示例脚本中的一个错字。)
【解决方案2】:

您需要修复您的awk 程序

如果字段 1 (file1) 存在于字段 3 (file2) 中,则打印 file2 中的所有记录:-

awk 'NR==FNR{A[$2];next}$3 in A' file1.txt file2.txt
some_key11 some_key11 some_text1
some_key22 some_key22 some_text2
...
some_keynn some_keynn some_textn

如果字段 1 (file1) 存在于字段 3 (file2) 中,则仅打印 file2 中的字段 1:-

awk 'NR==FNR{A[$2];next}$3 in A{ print $1 }' file1.txt file2.txt
some_key11
some_key22
...
some_keynn

【讨论】:

  • 问题有点不同!我不在乎其他文件*.txt 中是否存在某些键。我要匹配 some_text 字段!
猜你喜欢
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 2016-01-27
相关资源
最近更新 更多