Solarisで2つの文字列間の行を削除する

Solarisで2つの文字列間の行を削除する

デフォルトのawkまたはsedを使用して、2つのパターン間のすべての行を削除したいと思います。

foo.txt:

----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

output.txt:

----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

私はSolaris 5.10を使用しており、デフォルトのawkとsedのみを使用しています。スレッドの数は2つのパターンによって異なります。最初の文字列ではなく2番目の文字列を置き換える必要があります。両方のモードの違いはダッシュ数にあります。あなたが見るのはfoo.txt私の本当のファイルです。

答え1

 $ awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point

どのように動作しますか?

スクリプトには変数がありますf。 true(1) の場合、f削除する行の範囲内にあるものです。 false(0) であれば、印刷されるべき範囲にあるものです。

デフォルトfでは、プログラムが起動すると false です。

  • !f{print}

    ffalse の場合、すべての行を印刷します。

  • /----------------------/{f=!f;if (!f)print "Deleted up to this point"}

    破線で示された区切り線に達すると、値が反転しますf。 fがfalseの場合、「削除済み」メッセージを印刷します。

修正する

Solarisのデフォルトawkに問題があるようです。努力する:

nawk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

または、

/usr/xpg4/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

または、

/usr/xpg6/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

修正された質問に答えてください

$ awk ' /^---------------------------------------------------  Cap in MB/{print "Deleted up to this point"; f=0; z=""; next;} /^----------------------------------------------------------------------  Cap in MB/{f=1; if(z)print substr(z,2); z=""; print;next;}  f{z=z"\n"$0;next;} END{print substr(z,2);}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

答え2

awkの簡単な解決策は次のとおりです。長いダッシュ後に印刷をオフにし、短いダッシュ後に印刷をオンにします。

awk '
    !do_not_print {print}
    $0 == "----------------------------------------------------------------------  Cap in MB" {do_not_print = 1}
    $0 == "---------------------------------------------------  Cap in MB" {do_not_print = 0}
' <foo.txt >output.txt

答え3

私の意見は。 John1024に似ていますが、内容が1行になっているため読み取れません。
Solaris 8システムでテストされました。

/usr/xpg4/bin/awk \
    -v section_start='^----------------------------------------------------------------------  Cap in MB' \
    -v delete_marker='^---------------------------------------------------  Cap in MB' \
'
    $0 ~ section_start {
        for (i=1; i<=n; i++) 
            print line[i]
        n=0
        delete line
        print
        next    
    }
    {line[++n] = $0}
    $0 ~ delete_marker {
        n=1
        delete line
        line[1] = "Deleted up to this point"
    }
    END {for (i=1; i<=n; i++) print line[i]}
' foo.txt

関連情報