如果第一行包含一些文本,如何删除行中的三行? (AWK)

时间:2013-03-15 10:47:57

标签: linux awk row

我有一个这样的txt文件:

# RIR1
ABABABABABABABABAA
ABABABABABABABABBA
# WR
ABABABABABABABABAB
BABABBABABABABABAA
# BR2
ABABABABABABABBABA
ABBABABABABABABABA
# SL
AAABABABABABABBABA
AAABBABABABABABABA

我想删除SL和WR的所有数据(例如)。所以我只会:

# RIR1
ABABABABABABABABAA
ABABABABABABABABBA
# BR2
ABABABABABABABBABA
ABBABABABABABABABA

我知道如何删除一行开头或包含但不知道如何处理3行的行。

这是我用来删除包含某些内容的行:

awk ' $2 !~ /SL/ && $2 !~ /WR/ ' test.txt > test_new.txt

我想知道是否有办法将所有三条线一起移除。

3 个答案:

答案 0 :(得分:3)

使用打印标记的纯awk解决方案(受dogbane启发):

$ awk '/^#/{p=1}/^# (SL|WR)/,/^#/{p=0}p' file
# RIR1
ABABABABABABABABAA
ABABABABABABABABBA
# BR2
ABABABABABABABBABA
ABBABABABABABABABA

说明:

/^#/ {p=1}如果该行以#开头,则将打印标记p设置为1

/^# (SL|WR)/,/^#/{p=0}如果该行在# SL# WR的范围内,直到下一行开始#,则将打印标记设置为0

p如果打印标志非零,则运行默认块{print},否则0并且不打印任何内容。

此处的订单非常重要,首先在每个新记录中打开打印标记,并且只关闭记录SLWR


使用record seperators

您可以通过设置record变量重新定义awkRS的内容。默认情况下,每个记录都用换行符分隔,但对于您的示例,可以使用#作为记录分隔符,并且只打印第一个字段不是WRSL的记录:

$ awk '$1 != "SL" && $1 != "WR"' RS=# ORS=# file
# RIR1
ABABABABABABABABAA
ABABABABABABABABBA
# BR2
ABABABABABABABBABA
ABBABABABABABABABA
#

这种方法的一个小问题是最后一个记录分隔符。一个简单的解决方法是管道到sed '$d'

$ awk '$1 != "SL" && $1 != "WR"' RS=# ORS=# file | sed '$d'
# RIR1
ABABABABABABABABAA
ABABABABABABABABBA
# BR2
ABABABABABABABBABA
ABBABABABABABABABA

注意:变量ORS是我们需要设置的输出记录分隔符,因此输出中会显示#

答案 1 :(得分:3)

使用sed

删除# WR

sed -e '/^# WR/,/^#/ {/^# WR/d;/^#/!d}' file

删除# WR# SL块:

$ sed -e '/^# WR/,/^#/ {/^# WR/d;/^#/!d}' -e '/^# SL/,/^#/ {/^# SL/d;/^#/!d}' file

# RIR1
ABABABABABABABABAA
ABABABABABABABABBA
# BR2
ABABABABABABABBABA
ABBABABABABABABABA

或者,正如sudo_O所建议的那样:

sed -r '/^# (WR|SL)/,/^#/ {/^# (WR|SL)/d;/^#/!d}' file

答案 2 :(得分:0)

预处理文件:

awk '/#/{print x}1' file | awk '$2!="SL" && $2 !="WR"' RS=