我有 2 个文件
文件 1:
12342015010198765hello
12342015010188765hello
12342015010178765hello
Run Code Online (Sandbox Code Playgroud)
其每一行都包含固定位置的字段,例如,位置13 - 17用于account_id
文件2:
98765
88765
Run Code Online (Sandbox Code Playgroud)
其中包含account_ids的列表。
在 Korn Shell 中,我想从 file1 打印其位置13 - 17与account_idfile2中的一个匹配的行。
我做不到
grep -f file2 file1
Run Code Online (Sandbox Code Playgroud)
因为account_id在 file2 中可以匹配其他位置的其他字段。
我曾尝试在 file2 中使用模式:
^.{12}98765.*
Run Code Online (Sandbox Code Playgroud)
但没有用。
$ awk 'NR==FNR{a[$1]=1;next;} substr($0,13,5) in a' file2 file1
12342015010198765hello
12342015010188765hello
Run Code Online (Sandbox Code Playgroud)
NR==FNR{a[$1]=1;next;}
FNR 是迄今为止从当前文件读取的行数,NR 是迄今为止读取的总行数。因此,如果FNR==NR,我们正在读取第一个文件file2.
file2 中的每个 ID 都保存在 array 中a。然后,我们跳过其余的命令并跳转到该next行。
substr($0,13,5) in a
如果我们到达这个命令,我们正在处理第二个文件,file1.
如果从位置 13 开始的 5 个字符长的子字符串在 array 中,则此条件为真a。如果条件为真,则 awk 执行默认操作,即打印该行。
你提到尝试
grep '^.{12}98765.*' file2
Run Code Online (Sandbox Code Playgroud)
这使用扩展的正则表达式语法,这意味着这-E是必需的。此外,.*最后匹配没有任何价值:它将始终匹配。因此,尝试:
$ grep -E '^.{12}98765' file1
12342015010198765hello
Run Code Online (Sandbox Code Playgroud)
要获得这两行:
$ grep -E '^.{12}[89]8765' file1
12342015010198765hello
12342015010188765hello
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为[89]8765恰好与 file2 中感兴趣的 ID 匹配。当然,awk 解决方案在匹配的 ID 方面提供了更大的灵活性。