我想使用基本的 awk 或 sed 删除两个模式之间的所有行。
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 个图案之间的线数可能会有所不同。请注意,必须替换第二个字符串,而不是第一个字符串。请注意,两种模式之间的区别在于破折号的数量。你看到的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
。当f
为 true (1) 时,我们处于要删除的行范围内。当它为假(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 类似,但由于他的内容在一行中,因此无法阅读。
在 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