“grep -Ff file1 file2” 打印 file2 的所有行,而不是仅包含 file1 中的单词的行

“grep -Ff file1 file2” 打印 file2 的所有行,而不是仅包含 file1 中的单词的行

我有两个文件,file1.txt并且file2.txt.

file1.txt有 4000 行单字符串单词,file2.txt我有 498 个句子。

我想要grep file2其中的内容,并且如果在打印匹配项中找到file1该字符串。file1file2

我已经尝试过grep -fgrep -Ff,但它所做的只是打印文件的内容。

文件1.txt

something
somthingelse
maybe
ok
yes

文件2.txt

Hello there how are you
Here is another line ok
Nothing to see here maybe
Nope not here
yes 

预期产出

Here is another line ok
Nothing to see here maybe
yes



 wc -l file1.txt file2.txt
 4000 file1.txt
  498 file2.txt
 4498 total

答案1

检查file1as 中是否有空行,如果存在,则该行中包含的空字符串将与 中的每一行匹配file2。里面有一个空行file1

$ cat file1
something
somthingelse
maybe

ok
yes

$ grep -Ff file1 file2
Hello there how are you
Here is another line ok
Nothing to see here maybe
Nope not here
yes

yes包含单个空格字符的行将产生与匹配尚未与给定上述输入的行匹配的所有行相同的输出。

如果这两个文件都是带有 CRLF 分隔符的 MSDOS 文本格式(这对于 CSV 来说很常见),则只有该 CR 字符的一行(MSDOS/Windows 上的空行,但 Unix 上包含一个控制字符的行)也可以实现这一目的。

您可以过滤掉 before 使用的空行或空行file1

grep '[^[:space:]]' file1 | grep -Ff - file2

如果它们是 MSDOS 文件,您可能还希望从中删除这些 CR,file1否则只能word<CR>在行末尾的 if 中找到 in:file1file2

<file1 dos2unix | grep '[^[:space:]]' | grep -Ff - file2

答案2

除了 Ed 提到的空/空行和 CRLF 问题之外,如果 中存在 NUL 字节,也可能会发生这种问题file1,例如因为文件是用 UTF-16 或 UTF-16LE / UTF-16BE 编码的,而你grep没有t 在其输入中支持 NUL(Unix 上的文本文件不能包含 NUL 字节,UTF-16 编码的文本不能由文本实用程序处理,并且 UTF-16 不能是 Unix 语言环境中使用的代码集)。

例如,abc<newline> file1UTF-16BE 编码将包含字节 0x00 0x61 0x00 0x62 0x00 0x63 0x00 0x0a,对于 Unix,这是<NUL>a<NUL>b<NUL>c<NUL><newline>.grep用 C 编写且尚未更新为支持 NUL 输入的实现会将该行读入缓冲区,并且如果将其视为 C 字符串,则将被视为空字符串,因为 C 字符串是用 NUL 分隔的。

以 busybox 为例grep

$ echo abc | iconv -t UTF-16BE | busybox grep -Ff - <(echo whatever)
whatever

如果以 UTF-16LE (0x61 0x00 0x62 0x00 0x63 0x00 0x0a 0x00) 编码,则与认为第二行仅包含 NUL 相同。

在这种情况下,即使使用不会因 NUL 阻塞的实现,如果也以 UTF-16 编码,grep您也会在每一行上获得匹配,因为您随后将有效地在中查找 NUL 字节file2file2

您可以使用以下命令检查文件是否包含 NUL:

tr -cd '\0' < file1 | wc -c

这算他们。od -vAd -tc -tx1 | head例如,您可以通过查看前几个字节的值来了解它是否是 UTF-16 编码。

  • 普通的:

    $ echo abc | od -vAd -tc -tx1 | head
    0000000   a   b   c  \n
             61  62  63  0a
    0000004
    
  • UTF-16(带 BOM):

    $ echo abc | iconv -t UTF-16 | od -vAd -tc -tx1 | head
    0000000 377 376   a  \0   b  \0   c  \0  \n  \0
             ff  fe  61  00  62  00  63  00  0a  00
    0000010
    
  • UTF-16LE(小端):

    $ echo abc | iconv -t UTF-16LE | od -vAd -tc -tx1 | head
    0000000   a  \0   b  \0   c  \0  \n  \0
             61  00  62  00  63  00  0a  00
    0000008
    
  • UTF-16BE(大端)

    $ echo abc | iconv -t UTF-16BE | od -vAd -tc -tx1 | head
    0000000  \0   a  \0   b  \0   c  \0  \n
             00  61  00  62  00  63  00  0a
    0000008
    

您可以使用iconv -f UTF-16LE < file1.csv > file1.unix.csv例如来修复它们。

如果这些是 MSDOS / Windows 文件,dos2unix除了修复 MS Windows 文件的所有其他问题之外,还可以从 UTF-16 进行转换。对于 UTF-16LE 或 UTF-16BE,您需要传递一些--assume-utf16le--assume-utf16be告诉它它是什么。

答案3

问题在于字符串包含 SS 的文件 - 这会拾取所有内容

相关内容