たとえば、テキストに「一致」があるすべての行と、以前にインデントされていない行を探したいとします。
Container 1
some text
some text
matching text
some text
Container 2
some text
some text
Container 3
some text
matching text
私が望む結果は次のとおりです。
Container 1
matching text
Container 3
matching text
可能ですか?
答え1
1つの方法は次のとおりですsed
。
sed -n '/^[^[:blank:]]/b do # if line is not indented go to label do
//!{ # if line is indented and if it
/matching/H # matches, append it to hold space
}
$b do # if on last line go to label do
b # branch to end of script
: do # label do
x # exchange hold buffer w. pattern space
/\n.*matching/p # if current pattern space matches, print
' infile
インデントされていない一致行も印刷する場合(たとえば、Container matching stuff
次のインデントブロックに一致する行がない場合など)、最後の条件を変更して制限を/matching/p
削除\n.*
し、1行だけ残ってもパターンスペースを印刷します(インデントなし)。 )マッチ:
sed -n '/^[^[:blank:]]/b do
//!{
/matching/H
}
$b do
b
: do
x
/matching/p
' infile
答え2
awk '
!/^[[:blank:]]/ {unindented = $0}
/matching/ && /^[[:blank:]]/ {print unindented; print}
' file
空白で始まらない最後の行を覚えています。この値は、一致する行に到達するときに使用されます。
答え3
ここに別のものがありますsed
:
sed -ne'/^[[:space:]]/H;$x;//!{$!x;//!s/\n.*match/&/p;}' <in >out
Container 1
some text
some text
matching text
some text
Container 3
some text
matching text
それは以下を考慮するコンテナ空白ではなく連続した行で、空白以外の文字で始まり、印刷のみします。コンテナどちらが一致するのかマッチ2行目から1回以上。
次のように書くことができますgrep
。
sed ... | grep -E '^([^ ]| .*match)'
...あなたの例のような結果を得る...