一致するすべての行とインデントされていない前の行を印刷します。

一致するすべての行とインデントされていない前の行を印刷します。

たとえば、テキストに「一致」があるすべての行と、以前にインデントされていない行を探したいとします。

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)'

...あなたの例のような結果を得る...

関連情報