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

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

输入.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。

答案1

sed

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

这会将Next 行拉入模式空间(如果不在!la $t 行上)并检查模式空间是否匹配remove。如果不存在(意味着模式空间中的两行都不包含 string remove),它将P打印到第一个\newline 字符(即打印第一行)。然后它D删除第一个\newline 字符并重新开始循环。这样,模式空间中的线永远不会超过两条。


如果在 之前和之后添加来查看模式空间,可能会更容易理解N, P,循环:DlN

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)

答案2

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

答案3

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

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

!RT当最后一行不是一行时需要进行测试RS
RT, A傻瓜主义,是当前记录的实际文本RS
gensub也是一个傻瓜主义

如果您需要检查标记线火柴“删除”行中的任何位置,而不是一行等于“删除”,然后只需将记录分隔符更改为:

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

输出:

8B0F
8AC0
8AE4
8AE5

相关内容