如何在匹配保留之前删除行?

时间:2014-03-21 12:37:53

标签: regex bash sed awk

我有以下脚本删除与单词匹配的行之前的所有行:

str='
1
2
3
banana
4
5
6
banana
8
9
10
'

echo "$str"  | awk -v pattern=banana '
  print_it {print} 
  $0 ~ pattern {print_it = 1}
'

它返回:

4
5
6
banana
8
9
10

但我也希望包括第一场比赛。这是所需的输出:

banana
4
5
6
banana
8
9
10

我怎么能这样做?你对另一个命令有什么好主意吗? 我也试过了sed '0,/^banana$/d',但似乎只适用于文件,我想将它与变量一起使用。

如何使用awk在比赛前获得所有线路? 我的意思是。在正则表达式中使用香蕉,这将是输出:

1
2
3

4 个答案:

答案 0 :(得分:2)

sed -n '/^banana$/,$p'

应该做你想做的事。 -n指示sed默认不打印任何内容,p命令指定应打印所有地址行。这将在流上工作,并且与awk解决方案不同,因为这需要整行与“香蕉”相匹配。确切而你的awk解决方案只需要“香蕉”。在字符串中,但我复制你的sed示例。不确定你的意思"将它与变量"一起使用。如果你的意思是你想要字符串' banana'要处于变量中,您可以轻松地sed -n "/$variable/,\$p"(请注意双引号和转义的$)或sed -n "/^$variable\$/,\$p"sed -n "/^$variable"'$/,$p'。您也可以像使用awk一样echo "$str" | sed -n '/banana/,$p'

答案 1 :(得分:2)

awk应该:

echo "$str" | awk '/banana/ {f=1} f'
banana
4
5
6
banana
8
9
10

答案 2 :(得分:1)

只需反转awk中的命令:

echo "$str"  | awk -v pattern=banana '
  $0 ~ pattern {print_it = 1}   <--- if line matches, activate the flag
  print_it {print}              <--- if the flag is active, print the line
'

找到print_it时会激活pattern标记。从那一刻起(包括该行),您可以在标志为ON时打印行。以前print是在检查之前完成的。

答案 3 :(得分:1)

cat in.txt | awk "/banana/,0"

如果您不想保留匹配的行,则可以使用

cat in.txt | sed "0,/banana/d"