使用awk
或sed
如何选择出现在两种不同标记模式之间的线条?可能有多个部分标有这些模式。
例如:假设该文件包含:
abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu
并且起始模式是abc
,结束模式是mno
所以,我需要输出为:
def1
ghi1
jkl1
def2
ghi2
jkl2
我正在使用 sed 来匹配模式一次:
sed -e '1,/abc/d' -e '/mno/,$d' <FILE>
sed
或awk
有什么方法可以重复执行直到文件结束?
带有标志的awk
来触发打印:
$ awk '/abc/{flag=1;next}/mno/{flag=0}flag' file
def1
ghi1
jkl1
def2
ghi2
jkl2
这是如何工作的?
-
/abc/
匹配具有此文本的行,以及/mno/
行。 -
/abc/{flag=1;next}
设置找到文本abc
时的flag
。然后,它跳过该行。 -
/mno/{flag=0}
在找到文本mno
时取消设置flag
。 - 最后
flag
是具有默认操作的图案,即print $0
:如果flag
等于 1,则打印该行。
有关更详细的说明和示例,以及显示或不显示模式的情况,请参阅如何在两个模式之间选择线条?。
使用 sed
:
sed -n -e '/^abc$/,/^mno$/{ /^abc$/d; /^mno$/d; p; }'
-n
选项表示默认情况下不打印。
该模式查找仅包含 abc
到仅包含 mno
的行,然后执行{ ... }
中的操作。 第一个操作删除abc
行;第二条mno
线;p
打印剩余的行。 您可以根据需要放宽正则表达式。 超出abc
范围的任何行..mno
根本没有打印。
这可能对你有用(GNU sed(:
sed '/^abc$/,/^mno$/{//!b};d' file
删除除abc
和mno
开头的行之间的行之外的所有行
sed '/^abc$/,/^mno$/!d;//d' file
比普波东的{//!b};d
好两个角色
空的正斜杠//
表示:"重用最后一个使用的正则表达式"。 并且该命令的作用与更容易理解的相同:
sed '/^abc$/,/^mno$/!d;/^abc$/d;/^mno$/d' file
这似乎是POSIX:
如果 RE 为空(即未指定模式(,则 sed 的行为应与指定了在应用的最后一个命令中使用的最后一个 RE(作为地址或替代命令的一部分(一样。
从上一个响应的链接来看,在 Solaris 上运行ksh
为我做的是这样的:
sed '1,/firstmatch/d;/secondmatch/,$d'
-
1,/firstmatch/d
:从第 1 行到第一次找到firstmatch
时,删除。 -
/secondmatch/,$d
:从secondmatch
第一次出现到文件结束,删除。 - 分号分隔两个命令,这两个命令按顺序执行。
这样的东西对我有用:
文件.awk:
BEGIN {
record=0
}
/^abc$/ {
record=1
}
/^mno$/ {
record=0;
print "s="s;
s=""
}
!/^abc|mno$/ {
if (record==1) {
s = s"n"$0
}
}
使用: awk -f file.awk data
...
编辑:O_o Fedorqui解决方案比我的更好/更漂亮。
答案来自 仅显示 2 个匹配模式之间的文本?
firstmatch="abc"
secondmatch="cdf"
sed "/$firstmatch/,/$secondmatch/!d;//d" infile
这比AWK的应用程序效率高得多,请参阅此处。
perl -lne 'print if((/abc/../mno/) && !(/abc/||/mno/))' your_file
我尝试使用awk
来打印两个图案之间的线条,而模式2也匹配模式1。并且还应打印图案1行。
例如源
package AAA
aaa
bbb
ccc
package BBB
ddd
eee
package CCC
fff
ggg
hhh
iii
package DDD
jjj
应该有一个输出
package BBB
ddd
eee
其中模式 1 package BBB
,模式 2 package w*
。请注意,CCC
不是已知值,因此无法从字面上匹配。
在这种情况下,@scai的awk '/abc/{a=1}/mno/{print;a=0}a' file
和@fedorqui的awk '/abc/{a=1} a; /mno/{a=0}' file
都不适合我。
最后,我设法通过awk '/package BBB/{flag=1;print;next}/package w*/{flag=0}flag' file
解决了它,哈哈
再努力一点就会awk '/package BBB/{flag=1;print;next}flag;/package w*/{flag=0}' file
,也要打印图案2行,即
package BBB
ddd
eee
package CCC
这也可以通过对标志的逻辑运算和递增/递减运算来完成:
awk '/mno/&&--f||f||/abc/&&f++' file