Grepを使用すると、フィールド-A
および-B
を使用して、一致から前の行と次の行を取得できることを知っています。
ただし、多くの行が指定されていることに基づいて、マッチ間のすべての行を取り込みます。
grep -r -i -B 5 -A 5 "match"
5のみを受け取りたい番目 一致する前の行と5番目 一致した行に加えて一致した後の行で、その間の行を取得しません。
grep
でこれを行う方法はありますか?
使用するツールは、シフトと呼ばれます。これは基本的にステロイドのgrepです。並行してGrep。ふるいには、あなたが望むことを正確に行うための膨大な量のオプションがあります-具体的には、/テキストの後に続く/ない可能性のあるマッチに関連する特定の行を返します。
Siftはgo言語で書かれているので主流のgnuではなく、Linuxに問題なくインストールできることに驚かされます。 ITは、すべてのCPUの膨大な量のテキストを使用して並行して検索しますが、grepは同じことをするのに数週間かかります。
次の場合:
cat file
a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o
次に:
awk '
{line[NR] = $0}
/match/ {matched[NR]}
END {
for (nr in matched)
for (n=nr-5; n<=nr+5; n+=5)
print line[n]
}
' file
a
f match
k
d
i match
n
これは基本的にグレンのソリューションですが、Bash、Grep、およびsedで実装されています。
grep -n match file |
while IFS=: read nr _; do
sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
done
行番号が1未満の場合はsedエラーが発生し、ファイル内の行数より大きい行番号の場合は何も印刷されないことに注意してください。
これは最低限のものです。再帰的に動作させ、上記の行番号のケースを処理するには、ある程度の作業が必要です。
grep
だけではできません。 ed
がオプションの場合:
ed -s file << 'EOF'
g/match/-5p\
+5p\
+5p
EOF
スクリプトは基本的に、/ match /が一致するたびに、その5行前に行を印刷し、その後に5行、その後に5行を印刷します。
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile
ここでは、awkのsystem(command)
関数を使用して外部を呼び出していますsed
awkが5のパターンmatch
と一致した行を印刷するコマンド番目 試合の前後の行。
構文は簡単です。外部コマンド自体をスイッチと同様に二重引用符で囲み、コマンドに正確に渡すものをエスケープする必要があります。awk
オプション自体に関連する他のすべては引用符の外側にある必要があります。したがって、以下sed:
"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME
に翻訳する:
sed -n "NR-5p; NRp; NR+5p" FILENAME
@glennのサンプルテキストファイルを使用し、awkの代わりにPerlを使用します。
$ Perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex
同じ結果が得られますが、実行速度は速くなります。
a
f match
k
d
i match
n