匹配两个文件的相似第一行

匹配两个文件的相似第一行

我有 2 组文件。

文件一包含 ID 的 ex:

1111
2222
6666
3333
4444

文件二包含 ID 和用户名:

1873 Neil
1111 Roger
7632 Tim
3333 Oscar
8723 Greg
4444 Roy
6666 Patrick

我想提取 ID 和用户名,但只提取与文件 1 中 ID 相同的 ID 和用户名。我grep -f file1 file2在我制作的两个测试文件上执行了正常操作,其中几乎没有 ID,例如我刚刚发布的文件。但是,当我将其应用于两个正确的文件时,其中 file1 包含 3500 个 ID,File2 包含 12000 个 ID + 用户名,而不是提取两个文件中出现的 3500 行,而是提取 12000 行。然而,使用 2 个测试文件和一些虚拟 ID,它只会提取正确的 ID,而保留其他 ID。

有什么问题的提示吗?

答案1

尝试使用以下方法执行此操作相反grep,这会更合适:

$ join  <(sort file1) <(sort file2)

1111 Roger
3333 Oscar
4444 Roy
6666 Patrick

如果你的外壳缺少流程替代 <( ), 你可以做 :

sort file1 > new_file1
sort file2 > new_file2
join new_file1 new_file2

医生说:

join 将具有相同连接字段的每对输入行写入标准输出。

http://www.gnu.org/software/coreutils/manual/html_node/join-inspiration.html

注意事项:

文件需要根据排序键进行排序才能join正常工作,这就是我们使用一些文件描述符在后台使用流程替代http://mywiki.wooledge.org/ProcessSubstitution, 或者http://mywiki.wooledge.org/BashFAQ/024供共同使用。

答案2

grep匹配用户名与 ID 相同的行。join正确地将匹配限制为第一个字段,但需要排序的输入。根据输入awk可能是一个不错的选择:

awk 'FNR == NR { ids[$1]++; next } ids[$1]' ids users

或者更具可读性:

awk 'FNR == NR { ids[$1]; next } $1 in ids' ids users

输出:

1111 Roger
3333 Oscar
4444 Roy
6666 Patrick

解释

awk 程序分为两部分:一部分针对第一个文件进行评估,另一部分针对第二个文件进行评估。

第一个块仅针对第一个文件进行评估,并将 ids 保存在ids数组中。当读取时遇到这些 id 时,users将调用默认块 ( {print $0})。

相关内容