我有一个文件sample.txt
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
ord:RAM SAM
XY DUPL
KEY:UU
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
我根据关键字过滤订单ord:chandru
,key:ZZ
如果找到这些出现的情况,我将删除从连字符到连字符开始的订单,以给出这样的输出
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
答案1
如果你有 GNUawk
我建议这样:
gawk 'BEGIN{RS="-+\n"} $0=="" || /ord:chandru/ && /KEY:ZZ/ {ORS=RT; print}' sample.txt
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
just强制$0==""
打印空记录(如果您认为记录是由连字符字符串分隔的话,这就是文件第一行的解释方式)。
如果你不有gawk
,那么真正唯一的区别是您无法轻松捕获记录分隔符 - 在您提供的示例中这不是一个大问题,因为它是一个固定字符串。例如mawk
:
mawk 'BEGIN{RS="-------------\n"; ORS=RS} $0=="" || /ord:chandru/ && /KEY:ZZ/ {print}' sample.txt
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
-------------
答案2
这个应该是比较靠谱的
$ sed -n '1p; /ord:chandru/ {
N
N
/KEY:ZZ/{
N
/ord:chandru.*\n.*\n.*KEY:ZZ.*\n---.*/p
}
}' file
解释
-n
在我们提出要求之前不要打印1p
打印第一行,假设这会给我们一行连字符(此后,我们只打印连字符的尾部行)/ord:chandru/
找到模式N
读取下一行以允许我们使用该\n
字符来表示换行符p
打印匹配的行
答案3
使用awk:
$ awk 'BEGIN{RS="-------------"};/KEY:ZZ/&&/ord:chandru/{print RS$0}' sample.txt|egrep -v "^ *$"
输出:
-------------
ord:chandru SAM
XY DUPL
KEY:Z
-------------
ord:chandru SAM
XY DUPL
KEY:ZZ
答案4
sed -e '
/^ord:/,/^--*$/!b
H; /^ord:/h
/^--*$/!d; g
/^ord:chandru[ ]/!d
/\n[ ]*KEY:ZZ\n--*$/!d
' sample.txt
简要摘要:
/../,/../
=> 是范围运算符,用于选择一系列行,就像您的情况一样 from /ord:/ to /----/
。
我们松鼠将这些范围(一次一个范围)摇晃到保持区域。然后,当我们到达 range 的末尾时/---/
,我们知道是时候根据 `a) /ord:chandru/ && b) /key:ZZ/' 的标准来选择或拒绝这个特定范围了。