如果"file"具有空分隔项,如何使用"grep -f file"?

Pes*_*The 5 bash grep comm

我需要找到大量文件(空分隔的项目data2,data3存在于...) data1.完全匹配是必需的.

一切都很好用,grep -f data1 data2 data3 ...直到所有项目data1也为空分隔.

  1. 仅使用换行符 - 好的:

    $ cat data1
    1234
    abcd
    efgh
    5678
    $ cat data2
    1111
    oooo
    abcd
    5678
    $ grep -xFf data1 data2
    abcd
    5678
    
    Run Code Online (Sandbox Code Playgroud)
  2. 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)
  3. 现在,这两个data1data2包含空分隔的项目- 失败.似乎该-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)?

Cha*_*ffy 6

由于订单保留并不重要,您尝试匹配完全字符串,并且您可以使用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操作),这也将具有非常好的内存和性能特征.

  • @Pesa,`comm`非常快,你可以对每个文件进行一次`sort`s,而不是每次操作一次,只要你保留他们的结果. (2认同)