当字符串与awk或sed具有一定长度时删除行

时间:2016-08-29 16:11:53

标签: awk sed

我有一个包含4行的块的文件。结构看起来像这样

@A1
ABCGKJTGE
+
A4
@C1
SFDGDGDAD
+
C4

现在当每个块的第二行的字符串长度不等于9时,我希望删除4的块。在这种情况下,' B - 块'将被删除。所以我的outputfile看起来像这样

View

我会使用' awk'这样做,但不知道在这种情况下如何。

7 个答案:

答案 0 :(得分:1)

这个awk cmd完成了这项工作:

 awk '{a[NR]=$0}
    END{for(i=2;i<=NR;i+=4)
            if(length(a[i])==9)
                p[i-1]=p[i]=p[i+1]=p[i+2]=1
        for(x=1;x<=NR;x++)
                if(p[x])print a[x]}' file

这个想法是保存数组中的所有行,并检查有趣的行,并确定&#34;阻止&#34;应该打印还是不打印。

用你的例子测试:

kent$  cat f
A1
NNNNNNNNN
A3
A4
B1
NNNNNNN
B3
B4
C1
NNNNNNNNN
C3
C4

kent$  awk '{a[NR]=$0}
        END{for(i=2;i<=NR;i+=4)
                        if(length(a[i])==9)
                                p[i-1]=p[i]=p[i+1]=p[i+2]=1
                for(x=1;x<=NR;x++)
                        if(p[x])print a[x]}' f
A1
NNNNNNNNN
A3
A4
C1
NNNNNNNNN
C3
C4

答案 1 :(得分:1)

这是一个sed解决方案:

sed -E 'N;N;N;/.*\n[^\n]{9}\n.*\n/ !d' test.txt

(取决于您的操作系统,-E可能需要-r。)

这应该被理解为“当你找到一条线路时,再读三条线路(总共四条线路),寻找第二条线路长度恰好是9个字符,如果找到,则删除所有四行。“

对于包含此内容的test.txt

@A1
ABCGKJTGE
+
A4
@B1
ACDFS
+
B4
@C1
SFDGDGDAD
+
C4

输出结果为:

@A1
ABCGKJTGE
+
A4
@C1
SFDGDGDAD
+
C4

答案 2 :(得分:1)

$ cat tst.awk
NR%4 == 2 { lgth = length() }
{ rec = rec $0 ORS }
NR%4 == 0 {
    if ( lgth == 9 ) {
        printf "%s", rec
    }
    rec = ""
}

$ awk -f tst.awk file
@A1
ABCGKJTGE
+
A4
@C1
SFDGDGDAD
+
C4

答案 3 :(得分:1)

又一个AWK解决方案,受到之前解决方案的启发:

$ cat > yetanother.awk
{
    a=a $0 ORS                       # thanks @Ed Morton
}
NR%4==0 {                            # for every 4th record
    split(a,b,ORS)                   # split gathered a to b
    if(length(b[2]==9))              # if the second record in block
        printf "%s", a                # print it
    a=""                             # reset a
}

测试它:

$ awk -f yetanother.awk structure.txt
@A1
ABCGKJTGE
+
A4
@C1
SFDGDGDAD
+
C4

答案 4 :(得分:0)

awk '{
        arr[NR%4]=$0
        #dbg print "dbg: NR%4=" NR%4 "\tarr[2]="arr[2]"\tlen="length(arr[2])
        if (NR%4==0 && (length(arr[2]) == 9)) {
                print arr[1]"\n"arr[2]"\n"arr[3]"\n"arr[0]
        }
} ' data

输出

@A1
ABCGKJTGE
+
A4
@C1
SFDGDGDAD
+

这里一个棘手的部分是arr[NR%4]引用arr[0]。因此,我们必须在arr[4]语句中将“逻辑”arr[0]更改为print

如果每个“记录”的行数超过4行,则可以对该值进行参数化,然后使用它来驱动for循环以打印保存的记录,即

 for (i=1; i<=recSize; i++) {
   print arr[i]
 }
 print arr[0]

IHTH

答案 5 :(得分:0)

使用gnu awk多行记录

awk '
BEGIN{ RS="(^|\n)@[^\n]*\n" }
length($1) == 9 {printf("%s%s", prt, $0)}
{prt=RT}
'

答案 6 :(得分:0)

TXR中的解决方案:

@(repeat)
@@@head
@{line2 9}
@line3
@line4
@  (output)
@@@head
@line2
@line3
@line4
@  (end)
@(end)

执行命令

$ txr data.txr data
@A1
ABCGKJTGE
+
A4
@C1
SFDGDGDAD
+
C4