我有一个文件dict
,每行包含一个整数
123
456
我想在文件file
中找到完全 dict
中的整数的行。
如果我使用
$ grep -w -f dict file
我得到错误的匹配,例如
12345 foo
23456 bar
这些是假的,因为12345 != 123
和23456 != 456
。问题是-w
选项也将数字视为单词字符。由于-x
中的行可以包含其他文本,因此file
选项无效。请问最好的方法是什么?如果解决方案能够在dict
和file
大尺寸上提供进度监控和良好的性能,那就太棒了。
答案 0 :(得分:2)
在dict中添加单词边界,如下所示:
\<123\>
\<456\>
不需要-w参数。只需要:
grep -f dict文件
答案 1 :(得分:1)
您可以使用Python脚本轻松完成此操作,例如:
import sys
numbers = set(open(sys.argv[1]).read().split("\n"))
with open(sys.argv[2]) as inf:
for s in inf:
if s.split()[0] in numbers:
sys.stdout.write(s)
错误检查和恢复留待读者实施。
答案 2 :(得分:1)
使用awk
的一种相当通用的方法:
awk 'FNR==NR { array[$1]++; next } { for (i=1; i<=NF; i++) if ($i in array) print $0 }' dict file
<强>解释强>
FNR==NR { } ## FNR is number of records relative to the current input file.
## NR is the total number of records.
## So this statement simply means `while we're reading the 1st file
## called dict; do ...`
array[$1]++; ## Add the first column ($1) to an array called `array`.
## I could use $0 (the whole line) here, but since you have said
## that there will only be one integer per line, I decided to use
## $1 (it strips leading and lagging whitespace; if any)
next ## process the next line in `dict`
for (i=1; i<=NF; i++) ## loop through each column in `file`
if ($i in array) ## if one of these columns can be found in the array
print $0 ## print the whole line out
使用bash循环处理多个文件:
## This will process files; like file, file1, file2, file3 ...
## And create output files like, file.out, file1.out, file2.out, file3.out ...
for j in file*; do awk -v FILE=$j.out 'FNR==NR { array[$1]++; next } { for (i=1; i<=NF; i++) if ($i in array) print $0 > FILE }' dict $j; done
如果您有兴趣在多个文件上使用tee
,您可能会尝试这样的事情:
for j in file*; do awk -v FILE=$j.out 'FNR==NR { array[$1]++; next } { for (i=1; i<=NF; i++) if ($i in array) { print $0 > FILE; print FILENAME, $0 } }' dict $j; done 2>&1 | tee output
这将显示正在处理的文件的名称和找到的匹配记录,并将“日志”写入名为output
的文件。