file1
2つのファイルがあります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_FILE
PATTERN_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