"grep -Ff file1 file2"は、file1の単語を含む行の代わりにfile2のすべての行を印刷します。

"grep -Ff file1 file2"は、file1の単語を含む行の代わりにfile2のすべての行を印刷します。

file1.txt2つのファイルがありますfile2.txt

file1.txt4000行の単一の文字列単語があり、498のfile2.txt文があります。

私はその中に内容が欲しく、その文字列がgrep file2print matchで見つかったら欲しいです。file1file1file2

grep -f試してみましたが、grep -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に空白行があることを確認し、そうである場合、その行に含まれる空の文字列はasのすべての行と一致します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区切り文字(CSVと共通)を持つMSDOSテキスト形式の場合、そのCR文字には1行しかありません(MSDOS / Windowsでは空白行、Unixでは制御文字OK)。目的。

以下を使用する前に、空白行または空白行をフィルタリングできますfile1

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

MSDOSファイルの場合は、CRを削除することもできます。file1それ以外の場合は、word<CR>行末のifでのみ見つけることができます。file1file2

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

答え2

Edが述べた空/空行とCRLFの問題に加えて、この問題はファイルにNULバイトがある場合にも発生する可能性がありますfile1。たとえば、ファイルはUTF-16またはUTF-16LE / UTF-16BEでエンコードされており、入力はgrepNULをサポートしていません(UnixのテキストファイルにはNULバイトを含めることはできず、UTF-16でエンコードされたテキストはテキストユーティリティとして扱うことはできず、UTF-16はUnixロケールで使用されるコードセットにすることはできません)。

たとえば、abc<newline> file1UTF-16BEエンコーディングには、0x00 0x61 0x00 0x62 0x00 0x63 0x00 0x0aバイトが含まれており、Unixの場合、NUL入力をサポートするように更新されていないCで書かれた実装はバッファに行を読み込みます<NUL>a<NUL>b<NUL>c<NUL><newline>grepC 文字列として扱われ、C 文字列は NUL で区切られ、空の文字列として扱われます。

ビジーボックスを例に挙げましょうgrep

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

UTF-16LE(0x61 0x00 0x62 0x00 0x63 0x00 0x0a 0x00)でエンコードすると、2行目にはNULのみが含まれていると思います。

この場合、NULをブロックしない実装を使用してもgrepUTF-16でエンコードされている場合は、すべての行で一致を取得できます。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ファイルの場合は、dos2unixMS Windowsファイルに関連する他のすべての問題を解決するだけでなく、UTF-16から変換することもできます。 UTF-16LEまたはUTF-16BEの場合は、何かを伝えるか、--assume-utf16leそれ--assume-utf16beが何であるかを教えてください。

答え3

問題は、文字列にSSが含まれているファイルにあります。これはすべてを選択します。

関連情報