ログファイルtrace.log
があります。その中で、文字列<tag>
および</tag>
に含まれるコンテンツをgrepする必要があります。この文字列のペアには複数のセットがあり、最後のセットの間(つまり、ログファイルのtail
から)のコンテンツを返すだけです。
追加クレジット:コンテンツに「testString」が含まれている場合にのみ、2つの文字列に含まれるコンテンツを返す方法はありますか?
見てくれてありがとう。
編集:検索パラメーターは、異なる行に含まれており、約100行のコンテンツで区切られています。内容は私が求めているものです...
tac
を使用してファイルを逆方向に印刷し、_grep -m1
_を使用して1つの結果のみを印刷します。後読みと先読みは、_<tag>
_と_</tag>
_の間のテキストをチェックします。
_tac a | grep -m1 -oP '(?<=tag>).*(?=</tag>)'
_
このファイルを考える
_$ cat a
<tag> and </tag>
aaa <tag> and <b> other things </tag>
adsaad <tag>and last one</tag>
$ tac a | grep -m1 -oP '(?<=tag>).*(?=</tag>)'
and last one
_
編集:検索パラメーターは、異なる行に含まれており、約100行のコンテンツで区切られています。内容は私が求めているものです...
それからもう少しトリッキーです:
_tac file | awk '/<\/tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]};
/<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit};
p' | tac
_
ファイルを反転させ、p
フラグを使用して_<tag>
_がまだ出現しているかどうかを確認するという考え方です。 _</tag>
_が表示されたときに印刷を開始し、_<tag>
_が来たときに終了します(逆方向に読んでいるため)。
split($0, a, "</tag>"); $0=a[1];
は、_</tag>
_の前のデータを取得しますsplit($0, a, "<tag>" ); $0=a[2];
は_<tag>
_の後にデータを取得します次のようなファイルa
を指定します。
_<tag> and </tag>
aaa <tag> and <b> other thing
come here
and here </tag>
some text<tag>tag is starting here
blabla
and ends here</tag>
_
出力は次のようになります。
_$ tac a | awk '/<\/tag>/ {p=1; split($0, a, "</tag>"); $0=a[1]}; /<tag>/ {p=0; split($0, a, "<tag>"); $0=a[2]; print; exit}; p' | tac
tag is starting here
blabla
and ends here
_
私のように、システム管理者がボールをプレーできないため、tacにアクセスできません。
grep pattern file | tail -1
Grep以外の別の解決策はsedです:
tac file | sed -n '0,/<tag>\(.*\)<\/tag>/s//\1/p'
tac file
は逆順(cat
の逆順)でファイルを出力し、その後sed
は入力行0
から<tag>.*<\tag>
の最初の出現まで進みます。 <tag>.*<\tag>
を<tag>
の中にあった部分のみで置き換えます。 p
フラグは、-n
によって抑制された出力を出力します。
編集:<tag>
と</tag>
が異なる行にある場合、これは機能しません。そのためにsed
を使用できます:
tac file | sed -n '/<\/tag>/,$p; /<tag>/q' | sed 's/.*<tag>//; s/<\/tag>.*//' | tac
再びtac
を使用してファイルを逆方向に読み取り、最初のsed
コマンドはの最初の出現から読み取り、を検出すると終了します。間の行のみが印刷されます。次に、それを別のsed
プロセスに渡して、 'sを取り除き、最後にtac
で行を逆にします。
Perl -e '$/=undef; $f=<>; Push @a,$1 while($f=~m#<tag>(.*?)</tag>#msg); print $a[-1]' ex.txt
追加クレジット:コンテンツに「testString」が含まれている場合にのみ、2つの文字列に含まれるコンテンツを返す方法はありますか?
Perl -e '$/=undef; $f=<>; Push @a,$1 while($f=~m#<tag>(.*?)</tag>#msg); print $a[-1] if ($a[-1]~=/teststring/);' ex.txt
複数の行を処理する小さな未テスト awk:
awk '
BEGIN {retain="false"}
/<\tag>/ {retain = retain + $0; keep="false"; next}
/<tag>/ {keep = "true"; retain = $0; next}
keep == "true" {retain = retain + $0}
END {print retain}
' filename
ファイルの読み取りを開始します。を押すと、行を保持し始めます。を押すと停止します。別のをヒットした場合、保持された文字列をクリアして、やり直します。すべての文字列が必要な場合は、それぞれで印刷します