
ファイルの文字列を一致させるためにGNU grep
PCRE正規表現サポートを使用しています。-P
入力ファイルには、次の文字列を含む行が含まれています。
FOO_1BAR.zoo.2.someString:More-RandomString (string here too): 0.45654343
上記の行の数字2
と数字をキャプチャしたいと思います。0.45654343
正規表現を使用しました。
grep -Po ".zoo.\K[\d+](.*):\ (.*)$" file
しかし、私にとって結果は
2.someString:More-RandomString (string here too): 0.45654343
最初のキャプチャグループから最初の数字を取得でき2
、行末のキャプチャグループとも一致させることができます。ただし、2つのキャプチャグループ間の単語/行をスキップすることはできません。
私は(.*)
これらの単語を真ん中に捉えているグループがあることを知っています。私がやろうとしているのは、\K
それを無視するために他のものを含めることです。
grep -Po ".zoo.\K[\d+](.*):\K (.*)$" file
しかし、これは私に2番目のキャプチャグループを0.556984
。
(?:)
構文が次のような非キャプチャグループもあります。
grep -Po ".zoo.\K[\d+](?=.someString:More-RandomString (string here too)):\ (.*)$"
しかし、それは私に何も持ってこなかった。私がここで何を見逃しているのでしょうか?
答え1
grep
名前はg/re/p
ed
コマンドの後に表示されます。主な目的は、正規表現に一致する行を印刷することです。これはこの行の内容を編集することではありません。あなたはsed
(ストリームエディタ)またはawk
これのためにいます。
GNU以降grep
、一部の実装では、各行の一致部分(キャプチャグループの一致部分ではなく正規表現が一致する部分)を印刷するオプションをgrep
追加します。-o
すでにgrep
GNUに似た実装(使用-P
)またはpcregrep
PCREの正規表現サポートがあります。
pcregrep
実際に-o<n>
キャプチャグループの内容を印刷するオプションが追加されました。だからあなたはこれを行うことができます:
pcregrep -o1 -o2 --om-separator=' ' '.zoo.(\d+).*:\s+(.*)'
ただし、ここで明確な標準的な解決策は次のものを使用することですsed
。
sed -n 's/^.*\.zoo\.\([0-9]\{1,\}\).*:[[:space:]]\{1,\}/\1 /p'
または、perl正規表現が必要な場合は、perlを使用してください。
perl -lne 'print "$1 $2" if /\.zoo\.(\d+).*:\s+(.*)/'
GNUを使用してgrep
一致が別の行に表示されるのが気に入らない場合は、次のようにします。
$ grep -Po '\.zoo\.\K\d+|:\s+\K.*' < file
2
0.45654343
一致する区間の先頭がリセットされても、交互\K
に重なる2つの区間を削除できるわけではありません。
grep -Po '.zoo.(\K\d+|.:\ケイ。)
動作しません。動作しません(およびecho foobar | grep -Po 'foo|foob'
両方印刷)。最初に一致し、次に入力で他の潜在的な一致を探します。したがって、ofで始まるので、それ以降は一致するものが見つかりません。foo
foob
foo|foob
foo
grep
foo
b
bar
上記では、grep -Po '\.zoo\.\K\d+|:\s+\K.*'
シフトの2番目の部分だけを見ました。:<spaces><anything>
これは次の部分と一致しますが、それに続く部分だけでなく、入力のどこでもその部分を見つけるという.zoo.<digits>
意味でもあります。:<spaces><anything>
.zoo.<digits>
ただし、この問題を解決するには、別のPCRE特殊演算子を使用することです\G
。\G
トピックの先頭に一致します。単一の一致の場合は同じですが、複数の^
一致の場合(sed
/perl
フラグを考えてみてください)、行ですべての一致を検索しようとするのと同じで、前の一致が終了した後も一致します。その場合は、次のようにしてください。g
s/.../.../g
-o
grep
grep -Po '\.zoo\.\K\d+|(?!^)\G.*:\s+\K.*'
(?!^)
否定予測演算子はどこにありますか?行の先頭にない、\G
最後に成功した(空ではない)一致の後にのみ一致するため、最後に成功した一致.*:\s+\K.*
以降にのみ一致し、.foo.<digits>
置換の別の部分が行の最後まで一致するため、この一致のみが一致します。
次のように入力すると:
.zoo.1.zoo.2 tar: blah
これにより、以下が出力されます。
1
2
blah
しかし。これを望まない場合は、シフトの最初の部分が行の先頭でのみ一致するようにすることもできます。それはまるで
grep -Po '^.*?\.zoo\.\K\d+|(?!^)\G.*:\s+\K.*'
またはのような入力では依然として出力されます2
。置換の最初の部分でプレビュー演算子を使用し、その後にスペース以外の1つ以上を見つけてこの問題を解決できます(文字以外の問題を回避するためにも使用できます)。.zoo.2 no colon character
.zoo.2 blah:
:<spaces>
$
grep -Po '^.*?\.zoo\.\K\d+(?=.*:\s+\S.*$)|(?!^)\G.*:\s+\K\S.*$'
sed
その正規表現を説明するには複数ページのコメントが必要になる可能性があるため、まだ直接/ソリューションを使用しますperl
。