複数の行があるとしましょう。似たような以下のファイルに入れます。
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
場合。希望の出力:^.*cat
cat
Turbo is a cat
Coco is a black cat
*blah is a so and so cat*
どうすればいいですかgrep
?
grep
PS:私は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
指定された正規表現に基づいて行だけを選択して印刷します。
私は出力ラインをパイプして操作を実行するために追加のコマンドを使用する必要があると思います。
通常、行を選択して文字列を置き換えるので、sed
orを使用せ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
。置換が成功すると改行に分岐して改行として印刷され、そうでなければその行は削除されます。cat
cat
:print
P
d
これを1行で書くgnu sed
ことができます(例:5番目の項目まで印刷)。
sed -n 's/cat/&\n/5;tt;d;:t;P' infile