如果该行或下一行不包含特定字符串,则如何打印该行


8

Input.txt:

    8B0C
    remove
    8B0D
    remove
    8B0E
    remove
    8B0F
    8B10
    remove
    8B14
    remove
    8B15
    remove
    8B16
    remove
    8B17
    remove
    8AC0
    8AC1
    remove
    8AC2
    remove
    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

所需的输出:

    8B0F
    8AC0
    8AE4
    8AE5

如果该行或下一行不包含“删除”,我想打印一行。我正在使用solaris 5.10,KSH。


@don_crissti谢谢,如果您发布答案而不是发表评论,我可以将此问题标记为已回答。
ayrton_senna 2015年

Answers:


14

sed

sed '$!N;/remove/!P;D' infile

这会将Next行拉入模式空间(如果不在!latt $行上),并检查模式空间是否匹配remove。如果不存在(表示模式空间中的两行均不包含字符串remove),P则将其放大到第一个\newline字符(即,它打印第一行)。然后,它D上升到第一个\newline字符并重新开始循环。这样,模式空间中的行就不会超过两行。


如果在之前和之后添加以查看模式空间N,可能更容易理解PD循环:lN

sed 'l;$!N;l;/remove/!P;D' infile

因此,仅使用示例中的最后六行:

    8AC3
    remove
    8AE4
    8AE5
    8AE6
    remove

最后一条命令输出:

    8AC3 $
    8AC3 \ n删除$
    删除$
    删除\ n 8AE4 $
    8AE4 $
    8AE4 \ n 8AE5 $
    8AE4
    8AE5 $
    8AE5 \ n 8AE6 $
    8AE5
    8AE6 $
    8AE6 \ n删除$
    删除$
    删除$

这是一个简短的解释:

cmd输出cmd
l     8AC3$                  N # read in the next line
l     8AC3\n    remove$      D # delete up to \n (pattern space matches so no P)
l     remove$                N # read in the next line
l     remove\n    8AE4$      D # delete up to \n (pattern space matches so no P)
l     8AE4$                  N # read in the next line
l     8AE4\n    8AE5$        # pattern space doesn't match so print up to \n
P     8AE4                   D # delete up to \n
l     8AE5$                  N # read in the next line
l     8AE5\n    8AE6$        # pattern space doesn't match so print up to \n
P     8AE5                   D # delete up to \n 
l     8AE6$                  N # read in the next line
l     8AE6\n    remove$      D # delete up to \n (pattern space matches so no P)
l     remove$                # last line so no N 
l     remove$                D # delete (pattern space matches so no P)

5
awk '
    !/remove/ && NR > 1 && prev !~ /remove/ {print prev} 
    {prev = $0} 
    END {if (!/remove/) print}
' Input.txt 

2
gawk 'BEGIN{ RS="remove\n"; ORS="" }
      RT{ print gensub("[^\n]*\n$","","") }; !RT{ print }' file

上面的方法不会逐行读取Records ,而是从一个记录分隔符(RS)到下一个(或文件结尾)读取多行记录- RS本身就是“删除”行(包括其尾部的\ n)。

!RT需要时为最后一行是不是测试RS线。
RT是一种怪诞主义,是当前记录的实际文本RS
gensub也是怪诞主义

如果您需要检查与行中任何地方都匹配的 “删除” 标记行,而不是等于 “删除”的行,则只需将“记录分隔符”更改为:

`RS="[^\n]*remove[^\n]*\n"`  

输出:

8B0F
8AC0
8AE4
8AE5
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.