我试图获得第一次出现pattern1和最后一次出现模式2之间的所有行,这两种模式都是正则表达式
示例代码
TEXT
TEXT
[SUN_START]
[SUN_END]
[MON_START]
TEXT
[MON_END]
[TUE_START]
[TUE_END]
[WED_START]
TEXT
[WED_END]
TEXT
TEXT
我期待的输出是
[SUN_START]
[SUN_END]
[MON_START]
TEXT
[MON_END]
[TUE_START]
[TUE_END]
[WED_START]
TEXT
[WED_END]
模式为XXX_START和XXX_END
到目前为止我得到的是
cat /u01/app/oracle/admin/LNOPP1P/config/dbbackup_LNOPP1P.config | sed -n -e '/[[A-Z][A-Z][A-Z]_START]/,/[[A-Z][A-Z][A-Z]_END]/p'
但这不会保留换行符并像这样显示所有内容
[SUN_START]
[SUN_END]
[MON_START]
TEXT
[MON_END]
[TUE_START]
[TUE_END]
[WED_START]
TEXT
[WED_END]
我还想确保它只匹配以[[A-Z] _START]开头的行和与END
相同的行答案 0 :(得分:1)
此awk
应该有效:
awk '/_START\]/{p=1} p{a = a $0 ORS}/_END\]/{printf "%s", a; a="";}' file
简单逻辑:
答案 1 :(得分:1)
使用awk
grep
的解决方案
grep -Pzo '(?s)\[([A-Z]{3})_START\].*\n.*\[\1_END\]' file | sed 's/\x00/\n\n/'
你明白了,
[SUN_START] [SUN_END] [MON_START] TEXT [MON_END] [TUE_START] [TUE_END] [WED_START] TEXT [WED_END]
答案 2 :(得分:0)
您可以使用awk
:
awk '/\[..._START\]/{p=1}/\[..._END\]/{print;p=0}p||!NF' file
需要打印时设置变量p
。
!NF
允许保留空行。
答案 3 :(得分:0)
恕我直言,在不保存内存内容的情况下采用两遍方法是最简单,最强大的方法:
$ awk '
NR==FNR { if (/\[[A-Z]+_START\]/ && !beg) beg=NR; if (/\[[A-Z]+_END\]/) end=NR; next }
FNR>=beg && FNR<=end
' file file
[SUN_START]
[SUN_END]
[MON_START]
TEXT
[MON_END]
[TUE_START]
[TUE_END]
[WED_START]
TEXT
[WED_END]
考虑使用[[:upper:]]
代替[A-Z]
来跨区域设置进行移植。
我刚看到你在不同的答案下发表了这个评论:
Is it simple to invert this selection? select everything but the bit selected by this AWK ?
,答案是&#34;当然&#34;,只需更改脚本末尾的条件:
$ awk '
NR==FNR { if (/\[[A-Z]+_START\]/ && !beg) beg=NR; if (/\[[A-Z]+_END\]/) end=NR; next }
FNR<beg || FNR>end
' file file
TEXT
TEXT
TEXT
TEXT
或保持原始状态,但要做出动作&#34;接下来&#34;并添加默认&#34;打印&#34;对于其他每一行:
$ awk '
NR==FNR { if (/\[[A-Z]+_START\]/ && !beg) beg=NR; if (/\[[A-Z]+_END\]/) end=NR; next }
FNR>=beg && FNR<=end { next }
{ print }
' file file
TEXT
TEXT
TEXT
TEXT