入力
AA XXX Y1Y ZZZ GG dhz
rr (AAAa) XXX Y2Y ZZZ TT GGGG UU
出力
Y1Y
Y2Y
入力行は変化する可能性があります。Y1Y の前の XXX と Y1Y の後の ZZZ のみが一定です (これらは XXX と ZZZ の隣接行です)。Y1Y は何でもかまいません。例: Y1Y、Y2Y、Y1T など。
質問:awk や sed や grep で出力を取得するにはどうすればよいでしょうか? (あるいは、これよりよいツールはありますか?)
アップデート(問題): Y1Y に「.」があると動作しないのはなぜですか?
[user@notebook ~] echo 'XXX Y1Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
Y1Y
[user@notebook ~] echo 'XXX Y1.Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
[user@notebook ~]
答え1
grep
これを実行するには、提供されている PCRE 機能を使用できます。
$ grep -Po "(?<=XXX )\S+(?= ZZZ)" data.txt
Y1Y
Y2Y
詳細
このソリューションは、固定長の文字列に一致できる PCRE の後読み機能と先読み機能を利用します。
上記は、各 の後ろを\w+
見て かどうかを確認しXXX
、各 の先頭を見て かどうかを確認します。 であれば、一致です。を に切り替えると、一致したものだけを印刷するように指示されます。つまり\w+
、 です。ZZZ
-o
grep
\w+
フォローアップですが、sed でできますか?
この問題は を使用して解決できるとは思いませんsed
。私の見解では、2 つのアプローチがあります。
- 潜在的な一致をサイド変数に保存し、ZZZに遭遇した場合はそれを出力します。
- s/XXX ..私たちの文字列.. ZZZ/ ..私たちの文字列../
1 番はかなり手間がかかるようなので、挑戦するつもりはありません。2 番のアプローチでは次のようになります。
$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU
したがって、一致する行は問題なく見つかりますが、一致しない行については何も行われません。sed
これらの行を削除するように指示する方法があるかもしれませんが、その場合はこれが代替の解決策になります。