web-dev-qa-db-ja.com

awk固定テキストから始まり、最初の空白行まで

空白行で区切られた最初の「段落」または「セクション」のみを返すものにパイプしようとしています。 awkまたはsedを使用して、他のいくつかの回答に従って範囲を取得できると思いましたが、機能しないようです。

$ cat txt
Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

$ cat txt |awk '/^Package:/,/^$/'
Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

最初の「セクション」だけを返すべきではありませんか? (次のとおり: 固定テキストから始まり、最初の空白行まで および https://www.unix.com/Shell-programming-and-scripting/148692-awk- script-match-pattern-till-blank-line.html

  • grep -ve ^$を使用すると、空白行が削除されるため、特殊文字はありません。
  • 別のパーツを抽出しようとすると、両方の「セクション」からパーツが取得されます。

    $ cat txt |awk '/^Package:/,/^Version:/'
    Package: plasma-desktop
    Architecture: AMD64
    Version: 4:5.12.9.1-0ubuntu0.1
    Package: plasma-desktop
    Architecture: AMD64
    Version: 4:5.12.4-0ubuntu1
    
  • sed -n '/^Package:/,/^$/p'またはsed -n '/^Package:/,/^Version:/p'を使用すると、同等のawkと同じ結果が得られます。

最初の発生後にawkまたはsedを停止するにはどうすればよいですか?

2
codywohlers

これが、awkに段落モードがある理由です。

$ awk -v RS= 'NR==1' file
Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y

2番目のレコードを印刷することは、NR==1からNR==2への明らかな変更です。

$ awk -v RS= 'NR==2' file
Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.4-0ubuntu1
Supported: 3y

範囲式を使用しないでください-フラグを使用するよりも些細な問題のコードが非常に短くなりますが、要件が少しでも変更された場合は、完全な書き換えまたは複製条件が必要になります。そのため、sedまたはawkで/begin/,/end/を使用したい場合はいつでも、代わりにawkで/begin/{f=1} f{print} /end/{f=0}を使用してください。これにより、開始/終了行などを印刷するタイミング/方法をより詳細に制御できます。

5
Ed Morton

/begin/,/end/では、/begin/の一致が見つかるたびに「アクションフラグ」がオンになり、/end/の一致が見つかるとオフになります。 「開始」と「終了」の境界線も印刷されます。

入力に対する結果は次のとおりです(印刷された行には、以下のサンプルの後にコメントがあります):

  • '/^Package:/,/^$/'の場合:
    Package: plasma-desktop        #TURN ON
    Architecture: AMD64            #
    Version: 4:5.12.9.1-0ubuntu0.1 #
    Supported: 3y                  #
                                   #TURN OFF
    Package: plasma-desktop        #TURN ON
    Architecture: AMD64            #
    Version: 4:5.12.4-0ubuntu1     #
    Supported: 3y                  #
  • '/^Package:/,/^Version:/'の場合:
    Package: plasma-desktop        #TURN ON
    Architecture: AMD64            #
    Version: 4:5.12.9.1-0ubuntu0.1 #TURN OFF
    Supported: 3y

    Package: plasma-desktop        #TURN ON
    Architecture: AMD64            #
    Version: 4:5.12.4-0ubuntu1     #TURN OFF
    Supported: 3y

「パッケージ:」で始まる段落のみを印刷するには、次のように書くことができます。

sed -ne '/^$/q' -e '/^Package:/,$p' file

sedは、/^$/qのために空白行が見つかるとすぐにファイルの処理を終了します。

awkの場合:

awk '/^$/{exit};/^Package:/,0' file
1
Quasímodo

Quasímodo によるコメント

/begin/,/end/は、境界線を含むこれらの正規表現に一致する線を取得します。 beginは印刷をオンにし、endはオフにします。空白行の直後の行にもPackage:が含まれているため、再び印刷がオンになります。

sedを使用して/begin/0に変更できることに気づきました。これは最初から始まります。最初は1つしかないので、1回だけ一致します。

$ cat txt |sed -n '0,/^$/p'
Package: plasma-desktop
Architecture: AMD64
Version: 4:5.12.9.1-0ubuntu0.1
Supported: 3y
0
codywohlers