grepはfile2から正確なラインブロック(file1の内容)を抽出します。

grepはfile2から正確なラインブロック(file1の内容)を抽出します。

file12つのファイルがありますfile2

サンプルの内容は次のとおりですfile1

A B
C D
E F
G H

内容はfile2こんな感じです。

A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H

file1だから私は全体のコンテンツブロックを検索したいと思いますfile2。これは、出力に次の行のみを含める必要があることを意味します。

A B
C D
E F
G H

注: - 一緒にグループ化された行のみが出力の一部である必要があります。

答え1

grep複数行パターンの場合、これは非常に愚かですが、\nパターンとテキストのすべての改行をNUL文字に変換して比較して検索すると、\0問題は解決します。明らかに、\0出力も再翻訳する必要があります。\n

file1検索したいパターンが含まれていると仮定すると、コマンドは次のようになりますfile2

grep -aof <(tr '\n' '\0' < file1) <(tr '\n' '\0' < file2) | tr '\0' '\n'

特定ファイルの出力例:

A B
C D
E F
G H

説明する:

  • <(tr '\n' '\0' < file1)file1と同じですが、すべての改行文字がNUL文字に変換されたFIFO /名前付きパイプ/一時ファイルクラスオブジェクトを作成します。
  • <(tr '\n' '\0' < file2)同じことをしますfile2
  • grep -f PATTERN_FILE INPUT_FILEPATTERN_FILEそれからパターンを検索してくださいINPUT_FILE
  • フラグはバイナリファイルの一致を-a有効にします。grepそれ以外の場合は印刷できない文字(例:\0
  • -oフラグは、grep見つかった行全体ではなく一致するシーケンスのみを印刷します。
  • | tr '\0' '\n'左コマンド出力のすべてのNUL文字を改行文字に変換します。

答え2

以下のコードは厄介ですが、GNUでは機能しますawk

awk -v RS="$(<file1)" '{print RT}' file2

答え3

純粋なバッシュの楽しみのために

mapfile -t <file1
while read line ; do
    [ "$line" = "${MAPFILE[i++]}" ] || { ["$line" = "$MAPFILE" ] && i=1 || i=0; }
    [ $i -eq ${#MAPFILE[*]} ] && { printf "%s\n" "${MAPFILE[@]}"; i=0; }
done <file2

答え4

どの出力が欲しいのかわかりませんが、完全に線指向でない言語では簡単に実行できます(特に両方のファイルをメモリに読み込むことができる場合)。以下は、一致するアイテムの数を示すPythonスクリプトです。

import sys
find = open(sys.argv[1]).read()
hay = open(sys.argv[2]).read()
print("The text occurs", hay.count(find), "times")

file1一致する数を印刷しますか?最後の行を次に置き換えます。

print(find * hay.count(find))

本当に必要な場合は、すべてをコマンドライン呼び出しまたはエイリアスでラップできます。

python -c 'import sys; print("The text occurs", open(sys.argv[2]).read().count(open(sys.argv[1]).read()), "times")' file1 file2

関連情報