grepを使用すると、フィールド-A
を使用して-B
、一致から前の行と次の行を取得できることを知っています。
ただし、多くの行が指定されていることに基づいて、マッチ間のすべての行を取り込みます。
grep -r -i -B 5 -A 5 "match"
私は5を受け取りたい番目の試合前のラインと5 番目のマッチラインに加えて、試合後の行をとの間に線を取得できません。
これを行う方法はありgrep
ますか?
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
/match/ {matched[NR]}
か?コマンド全体として配列や変数を見たことはありません。一致した各行の現在のレコード番号を配列に入れていますか?
key in array
。私がやっていることは、パターンが表示される行番号を覚えていることです
それだけではできませんgrep
。がed
オプションの場合:
ed -s file << 'EOF'
g/match/-5p\
+5p\
+5p
EOF
スクリプトは基本的に、/ match /のすべての一致に対して、その5行前、次に5行、そしてその後5行を印刷します。
grep
答えではありませんが、「Xではできないが、Yでできる」という答えは、OPの質問に答えるだけでなく、代替手段も提供するため、依然として有効な答えです。それはうまくいくでしょう。これは、ここでの有効なタイプの回答です。
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile
ここでは、awkの関数を使用して外部コマンドを呼び出し、awkがpattern と一致した行を、一致の前後の5 行目で出力します。system(command)
sed
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
grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'