在打印不匹配的图案时,awk意外地重复打印



我将数据组织为行(没有列)。">name"one_answers"data",使得:


>name1
textA
>name2
textB
>name3
textC

我想删除具有给定名称和相关数据的行-例如,删除>name3的数据,这意味着>name3行和textC行都应该被删除。

我正在使用:

awk 'BEGIN {RS = ">"; ORS = ""} !/name3/ {print">"; print $0}' FILE

但是,输出如下所示:


>>name1
textA
>name2
textB

我尝试了几个替代方案,但我没有设法使第一行正确(例如,无论是">";

记录分隔符为>
文件的第一个字符为>
因此,文件的第一个记录是第一个记录分隔符前的空字符串

你想:

awk '
BEGIN {RS = ">"; ORS = ""}
length && $1 != "name3" {print RS $0}
' file
>name1
textA
>name2
textB

另一种解决问题的方法:

paste - - < file | grep -v '>name3[[:blank:]]' | tr 't' 'n'

使用正匹配的awk想法:

$ awk '$1 == ">name3" { getline; next }1' file
>name1
textA
>name2
textB

地点:

  • 如果第一列在>name3上匹配(并且在>name33上不匹配),则读取下一行(getline),然后跳过处理下一行输入;有效地跳过当前和下一行
  • 任何没有被match/getline捕获的行都由独立的1(又名true,又名将当前行打印到标准输出)处理

如果您的数据行只有一行,则可以使用

$ awk -v var="name3" 'set == 1{set = 0; next}
$0 ~ var{set = 1; next}1' file
>name1
textA
>name2
textB

如果有更多行,则使用

$ awk -v var="name3" '/>/{set = 0}
set == 1{next}
$0 ~ var{set = 1; next}1' file2
>name1
textA
>name2
textB
textB

$ cat file2
>name1
textA
>name2
textB
textB
>name3
textC
textC

你也可以这样做(不漂亮,但很有效):

awk 'BEGIN { RS = "n>name3ntextCn*" } 1' file
  • n是第4行结束符。
  • n为第5行结束行。
  • n*是第6行及以上的行尾。

问题在于您的awk必须能够为RS变量设置正则表达式。

由于在第一个记录分隔符之前没有记录(即它只适用于第1行),因此在主块中使用一个简单的条件来修复它:

awk 'BEGIN {RS = ">"; ORS = ""} !/name3/ {if(NR>1){print">"}; print $0}' FILE

我在测试输入中添加了重复项和额外的填充…

1  
2  
3       1  >name1
4       2  textA
5       3  >name2
6       4  textB
7       5  >name3
8       6  textC
9  
10       7  >name1
11       8  textA
12       9  >name2
13      10  textB
14      11  >name3
15      12  textC
16  
17  

mawk 7 ORS= RS='[>]name3[nr]+[^nr]+[nr]*'
1  >name1
2  textA
3  >name2
4  textB
5  >name1
6  textA
7  >name2
8  textB

......和输出现在是无间隙

给定:

cat file
>name1
textA
>name2
textB
>name3
textC

您可以使用sed删除匹配和下面的行:

sed -e '/^>name2$/,+1d' file 
>name1
textA
>name3
textC

使用awk你可以做:

awk -v p="^>name1$" '
$0~p{cnt=2} 
--cnt>=0{next} 
1' file

打印:

>name2
textB
>name3
textC

同样,对于sed,您可以使用范围匹配:

sed -e '/^>name2$/,/^[^>]/d' file
>name1
textA
>name3
textC

也适用于awk:

awk '/^>name2$/,/^[^>]/{next} 1' file
# same output

注意:如果您有>name2>name20和/或200,您应该使用锚来确保完全匹配。上面使用的^$

最新更新