sedの逆マッチングは、改行まですべての行を印刷します。

sedの逆マッチングは、改行まですべての行を印刷します。

新しい行まで、1つの段落で逆方向一致を印刷する必要があります(逆方向一致パターンは、段落の最初の行と単語の末尾にあります)。

sed.を試しましたが、うまく[^text]いきません。

私のパターン文字列は単語の末尾にありますxxx_yyyy: ZZZ

sed -n '/[^ZZZ]$/,/^$/p'動作しません。

誰かがここで何が間違っているかを修正できますか?

入力する:

sometext tobe here xxx_yyyy: ZZZ
sjhdajsh 
skdjah
hjk 

sometext tobe here xxx_yyyy: AAA 
sjhdajsh 
skdjah 
hjk 

sometext tobe here xxx_yyyy: ZZZ
sjhdajsh
skdjah 
hjk

希望の出力:

含まれていない段落を印刷する必要がありますxxx_yyyy: ZZZ

sometext tobe here xxx_yyyy: AAA
sjhdajsh 
skdjah 
hjk

答え1

awk以下を使用するよりも簡単ですsed

$ awk -v RS='' -F '\n' '!($1 ~ /ZZZ$/)' file
sometext tobe here xxx_yyyy: AAA
sjhdajsh
skdjah
hjk

まず、レコード区切り文字をRS空の文字列に設定します。この特殊値を使用すると、RS1つawk以上の空白行で区切られた各段落が1つのレコードとして扱われます。段落の各行をフィールドとして処理するように指示-F '\n'します。awk

!($1 ~ /ZZZ$/)最初のフィールド(最初の行)が次の基準を満たすすべてのレコード(段落)に対してテストが適用されます。いいえ文字列で終わりますZZZ。そのような各段落が印刷される。

各出力セクションの後に空白行を追加するには、コマンドライン(コードの前)-v ORS='\n\n'に追加します。awkawk


それでsedあなたはできます

$ sed '/ZZZ$/,/^$/d' file
sometext tobe here xxx_yyyy: AAA
sjhdajsh
skdjah
hjk

つまり、「ZZZ任意の行で始まり、次の空行で終わるすべての行を削除」します。でsed式を使用することもできます。しかし、もしかしたら参考にしてください/ZZZ$/,/^$/!psed -nZZZその他段落の最初の行以外の行も削除を引き起こします。

この問題は明らかに解決することができます(段落を1行ずつ読み、予約済みスペースに入力して、何を印刷して何を捨てるかを決定することによって)。しかし、awk上記のバリエーションを使用するよりも面倒です。


[^ZZZ]質問に使用した表現について言及するだけです。これ[^Z]はではなく、すべての単一文字とまったく同じで一致しますZ。同様に、[^text]または以外のすべての単一文字が一致します。[^etx]etx

関連情報