我需要找到大量文件(空分隔的项目data2,data3存在于...) data1.完全匹配是必需的.
一切都很好用,grep -f data1 data2 data3 ...直到所有项目data1也为空分隔.
仅使用换行符 - 好的:
$ cat data1
1234
abcd
efgh
5678
$ cat data2
1111
oooo
abcd
5678
$ grep -xFf data1 data2
abcd
5678
Run Code Online (Sandbox Code Playgroud)data2-包含null分隔的项目确定时-z:使用
$ printf '1111\0oooo\0abcd\0005678' > data2
$ grep -zxFf data1 data2 | xargs -0 printf '%s\n'
abcd
5678
Run Code Online (Sandbox Code Playgroud)现在,这两个data1和data2包含空分隔的项目- 失败.似乎该-z选项不适用于指定的文件-f:
$ printf '1234\0abcd\0efgh\0005678' > data1
$ grep -zxFf data1 data2 | xargs -0 printf '%s\n'
$
Run Code Online (Sandbox Code Playgroud)问题是我确实需要两个文件都有空分隔的项目.明显的解决方法可能是(例如)一个好的旧while循环:
while IFS= read -rd '' line || [[ $line ]]; do
if grep -zqxF "$line" data2; then
printf '%s\n' "$line"
fi
done < data1
Run Code Online (Sandbox Code Playgroud)
但是因为我有很多带有很多项目的文件,所以这将非常缓慢!有没有更好的方法(我不坚持使用grep)?
由于订单保留并不重要,您尝试匹配完全字符串,并且您可以使用GNU工具,而不是使用fgrep我建议的comm -z.
$ printf '%s\0' 1111 oooo abcd 005678 >data2
$ printf '%s\0' 1234 abcd efgh 005678 >data
$ comm -z12 <(sort -uz <data) <(sort -uz <data2) | xargs -0 printf '%s\n'
005678
abcd
Run Code Online (Sandbox Code Playgroud)
如果您生成的文件首先排序(因此可以省略sort操作),这也将具有非常好的内存和性能特征.