
デフォルトの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}
f
false の場合、すべての行を印刷します。/----------------------/{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