1行からn番目のパターン発生を印刷します(含む)。

1行からn番目のパターン発生を印刷します(含む)。

複数の行があるとしましょう。似たような以下のファイルに入れます。

Turbo is a cat. cats are good. cats are not dog.
Coco is a black cat. cats are furry. cats are not dog.

単語が最初に(またはn番目)表示されるまで具体的にキャプチャしたいgrep場合。希望の出力:^.*catcat

Turbo is a cat
Coco is a black cat
*blah is a so and so cat*

どうすればいいですかgrep

grepPS:私はonly(または他のバリエーション)を使って答えを得たいと思います。

^.*cat.PS:私はgrepをして削除するために何もしたくありません。「。」 。一般的な答えが欲しいです。

答え1

そしてPOSIX grep、行全体を印刷するか、行内容をまったく印刷しないかを選択できます。この行を変換するには、sedやawkなどの他のツールを使用する必要があります。最初の項目まで印刷するには、次のようにしますcat

sed -n 's/cat.*/cat/'
awk 'sub(/cat.*/,"")'

ほとんどの印刷窒素発生する状況はさらに複雑です。

sed -n 's/cat/&\
/3; T; P'
awk 'gsub(/cat/,"&\n") >= 3 {split($0, a, "\n"); printf "%s%s%s\n", a[1], a[2], a[3]}'

そしてGNU grep、この-oオプションを使用して、行の一致する部分のみを印刷できます。-P次のオプションを使用してPerl構文を有効にします。貪欲ではない数量子利用可能。

grep -P -o '^(.*?cat){1}'

中かっこ内の数字を実際の数字に置き換えます。Ncat印刷する最後の項目の位置。

拡張正規表現(-E)を使用して同じ内容を表現できますが、これには計算する部分のサイズ(catここで)に応じてサイズが指数関数的に増加する複雑な正規表現が必要です。

答え2

grep指定された正規表現に基づいて行だけを選択して印刷します。

私は出力ラインをパイプして操作を実行するために追加のコマンドを使用する必要があると思います。

通常、行を選択して文字列を置き換えるので、sedorを使用せawkずに操作を完了できます。grep

以下に解決策がありますawk。以下を使用してください。

awk -v word=cat -v n=2 'BEGIN {wordlength=length(word);} {line=$0;outputline="";position=index(line,word);for (i=1;position>0 && i<=n; i++) { outputline=outputline substr(line,1,position+wordlength-1);line=substr(line,position+wordlength);position=index(line,word);  } if (i!=1) {print outputline;}}'

word検索する文字列と必要なn回数を設定する必要があります。

テストを受ける:

$ awk -v word=cat -v n=2 'BEGIN {wordlength=length(word);} {line=$0;outputline="";position=index(line,word);for (i=1;position>0 && i<=n; i++) { outputline=outputline substr(line,1,position+wordlength-1);line=substr(line,position+wordlength);position=index(line,word);  } if (i!=1) {print outputline;}}' file
Turbo is a cat. cat
Coco is a black cat. cat

答え3

回避策は次のとおりですsed(たとえば、2番目の項目を印刷して埋め込み、2自分の番号に置き換えます)。

sed -n 's/cat/&\
/2
t print
d
:print
P' infile

これにより、viaの自動印刷が無効になり、+newlineの2回目の発生を置き換えようとします-n。置換が成功すると改行に分岐して改行として印刷され、そうでなければその行は削除されます。catcat:printPd


これを1行で書くgnu sedことができます(例:5番目の項目まで印刷)。

sed -n 's/cat/&\n/5;tt;d;:t;P' infile

関連情報