Grep 或 awk 在 2 个大文件之间,其中 file1 是模式文件,file2 包含数据

Tee*_*ess 3 grep awk text-processing

File1有固定长度的数字,每行一个数字:

1234
5678
1345
Run Code Online (Sandbox Code Playgroud)

File2包含“key=value”格式的数据字段:

abc:def=1999,xyz=1234;
abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;
Run Code Online (Sandbox Code Playgroud)

我需要获取字段与 中的任何数字匹配的那些File2行,但该字段在模式匹配时被忽略。所以,我的结果应该是这样的:defFile1xyz

abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;
Run Code Online (Sandbox Code Playgroud)

Phi*_*pos 7

我总是忘记大多数awk命令,这对我的老大脑来说太多了,所以我提供了一个sed替代方案

\n
sed \'/^[0-9]*$/H;G;/def=\\([0-9]*\\),.*\\n\\1/P;d\' file1 file2\n
Run Code Online (Sandbox Code Playgroud)\n

这个想法是收集保留空间中的数字file1并使用反向引用来识别 file2 中包含以下数字的那些行:def=

\n
    \n
  • 该模式^[0-9]*$匹配仅包含数字的行,这些行是file1行,我们将其附加到H旧空间
  • \n
  • G将保留空间附加到模式空间,因此我们拥有模式空间中的file2行和所有数字file1
  • \n
  • 该模式寻址在换行符之后重复/def=\\([0-9]*\\),.*\\n\\1后面的数字(反向引用)的所有行(因此它是保留空间集合的一部分)。打印那些没有附加内容的行def=\\1P
  • \n
  • d抑制进一步的输出。你可以使用选项-n代替
  • \n
\n

更新:视觉解释

\n

正如埃德指出的那样,我的解释显然对每个人都没有帮助。如果您更像是一个“视觉思考者”,我将尝试说明其中的原理。请记住,这sed不是编程工具,而更像是一个自动文本编辑器,其保留空间作为“剪贴板”,而行被读入模式空间,在那里完成工作。

\n

现在我按照建议在HG命令后显示两个空格:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
模式空间保留空间评论
1234\xe2\x90\xa41234附加H到(空)保留空间并嵌入换行符
1234\xe2\x90\xa4\xe2\x90\xa41234\xe2\x90\xa41234追加G回模式空间,添加另一个换行符
5678\xe2\x90\xa4 1234\xe2\x90\xa45678读取下一行时保留保留空间,因此下一行H会附加下一个数字
5678\xe2\x90\xa4\xe2\x90\xa4 1234\xe2\x90\xa45678\xe2\x90\xa4 1234\xe2\x90\xa45678再次追加回模式空间,但仍然与def=模式不匹配
file1为了便于阅读,跳过第三行
abc:def=1999,xyz=1234;\xe2\x90\xa4 1234\xe2\x90\xa45678与模式不匹配^[0-9]*$,因此H不执行
abc:def=1999,xyz=1234;\xe2\x90\xa4\xe2\x90\xa4 1234\xe2\x90\xa45678\xe2\x90\xa4 1234\xe2\x90\xa45678G被执行
\n
\n

P现在看看如何应用命令的地址模式(用作\\n换行符的占位符):

\n
abc:def=1999,xyz=1234;\\n\\n1234\\n5678\n    def=####,         .*                 #### stands for `[0-9]*`, but the back reference\n                                         as `\\1` is not found: no match\n\nabc:def=5678,xyz=1234;\\n\\n1234\\n5678\n    def=####,         .*      \\n####     here, the match is repeated as `\\1`,so we know\n                                         the `def` number has been listed in `file1` \n
Run Code Online (Sandbox Code Playgroud)\n