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
中有什么方法可以重复执行直到文件结束? #1 楼
必要时使用带有标志的awk
来触发打印:$ awk '/abc/{flag=1;next}/mno/{flag=0}flag' file
def1
ghi1
jkl1
def2
ghi2
jkl2
这是如何工作的?
/abc/
与具有/mno/
的行匹配具有此文本的行。 当找到文本
/abc/{flag=1;next}
时,flag
设置abc
。然后,它跳过了这一行。 当找到文本
/mno/{flag=0}
时,flag
取消设置mno
。最后一个
flag
是具有默认操作的模式,即print flag
:如果q4312079q等于1,则打印行。 br /> 有关更详细的描述和示例,以及显示或不显示图案的情况,请参阅如何在两个图案之间选择线?。
#2 楼
使用sed
:sed -n -e '/^abc$/,/^mno$/{ /^abc$/d; /^mno$/d; p; }'
-n
选项意味着默认情况下不打印。然后执行abc
中的动作。第一个动作删除mno
行;第二条{ ... }
线;然后abc
打印剩余的行。您可以根据需要放松正则表达式。 mno
.. p
范围以外的任何行都不会被打印。评论
@JonathanLeffler我可以知道使用-e的目的是什么
– Kasun Siyambalapitiya
16 Dec 6'在4:33
@KasunSiyambalapitiya:通常,这意味着我喜欢使用它。形式上,它指定下一个参数是sed应该执行的脚本(的一部分)。如果要或需要使用几个参数来包含整个脚本,则必须在每个这样的参数之前使用-e;否则,请使用-e。否则,它是可选的(但显式)。
–乔纳森·莱弗勒(Jonathan Leffler)
16 Dec 6'在4:41
真好! (与awk相比,我更喜欢使用sed。)当使用复杂的正则表达式时,最好不必重复它们。是否可以删除“选定”范围的第一行/最后一行?还是先将d应用于直到第一个匹配的所有行,然后再将d应用于从第二个匹配开始的所有行?
–hans_meine
16 Dec 8'在10:12
(回复我自己的评论。)如果仅要剪切一个部分,我可以尝试解决此问题,例如对于LaTeX,请使用sed -n'1,/ \\\ begin {document} / d; / \\ end {document} / d; p'。 (这有点作弊,因为第二部分并没有删除到文档末尾,而且我不知道如何按照OP的要求剪切多个部分。)
–hans_meine
16 Dec 8'在10:50
@JonathanLeffler插入$标记的原因是什么,如/ ^ abc $等
– Kasun Siyambalapitiya
17年1月25日在4:58
#3 楼
这可能对您有用(GNU sed):sed '/^abc$/,/^mno$/{//!b};d' file
删除除以
abc
和mno
开头的行之间的行以外的所有行评论
!d; // d高尔夫2个字符更好:-) stackoverflow.com/a/31380266/895245
– Ciro Santilli郝海东冠状病六四事件法轮功
15年7月13日在9:54
这太棒了。 {//!b}可以防止abc和mno包含在输出中,但是我不知道如何。你能解释一下吗?
–布伦丹
17年2月16日在17:44
@Brendan指令//!b读取当前行是否不是与范围匹配的行之一,请中断并打印这些行,否则将删除所有其他行。
–potong
17年2月17日在1:14
#4 楼
sed '/^abc$/,/^mno$/!d;//d' file
比potpotong的{//!b};d
高两个字符,而空的正斜杠//
的意思是:“重用最后使用的正则表达式”。并且该命令与更易于理解的命令相同: sed的行为就像指定了所应用的最后一个命令中使用的最后一个RE(作为地址或作为替代命令的一部分)。
评论
我认为第二个解决方案将一无所获,因为第二个命令也是一个范围。但是首先赞扬。
–potong
15年7月13日在14:20
@potong真的!我必须研究更多第一个为什么工作的原因。谢谢!
– Ciro Santilli郝海东冠状病六四事件法轮功
15年7月13日在14:22
#5 楼
从上一个响应的链接来看,为我做的一个在Solaris上运行ksh
的操作是:第1行,直到第一次找到1,/firstmatch/d
,删除。firstmatch
:从/secondmatch/,$d
的第一次出现到文件末尾,删除。分号分隔两个命令,它们在顺序。
评论
很好奇,为什么范围限制器(1,)在/ firstmatch /之前?我猜这也可以写成'/ firstmatch / 1,d; / secondmatch,$ d'吗?
–卢克·戴维斯(Luke Davis)
18 Jun 25'在0:40
使用“ 1,/ firstmatch / d”表示“从第1行开始,直到第一次找到'firstmatch',然后删除”。而使用“ / secondmatch /,$ d”则表示“从'secondmatch'的第一次出现到文件结尾,删除”。分号将两个命令分开,两个命令按顺序执行。
– FanDeLaU
18/12/20在17:18
#6 楼
perl -lne 'print if((/abc/../mno/) && !(/abc/||/mno/))' your_file
评论
很高兴知道perl等效项,因为它可以很好地替代awk和sed。
– akhan
17 Mar 8 '17 at 23:46
#7 楼
这样的东西对我有用:file.awk:
BEGIN {
record=0
}
/^abc$/ {
record=1
}
/^mno$/ {
record=0;
print "s="s;
s=""
}
!/^abc|mno$/ {
if (record==1) {
s = s"\n"q4312078q
}
}
使用:
awk -f file.awk data
... 编辑:O_o fedorqui解决方案比我的更好/更漂亮。
评论
在GNU awk中,if(record = 1)应该是if(record == 1),即double =-请参见gawk比较运算符
–乔治·霍金斯(George Hawkins)
2014年5月26日晚上8:53
#8 楼
Don_crissti的答案来自仅显示2个匹配模式之间的文本?评论
我认为链接时间比较在这里没有多大意义,因为问题的要求完全不同,因此也有解决方案。
– fedorqui'停止伤害'
2015年9月11日15:11
我不同意,因为我们应该有一些比较答案的标准。只有少数具有SED应用程序。
–LéoLéopoldHertz준영
2015年9月11日在16:10
#9 楼
我尝试使用awk
在两个模式之间打印行,而pattern2也匹配pattern1。并且pattern1线也应该被打印。 例如
源
package AAA
aaa
bbb
ccc
package BBB
ddd
eee
package CCC
fff
ggg
hhh
iii
package DDD
jjj
输出应为
package BBB
ddd
eee
pattern1是
package BBB
,pattern2是package \w*
。请注意,CCC
不是一个已知值,因此无法进行字面匹配。在这种情况下,@ scai的
awk '/abc/{a=1}/mno/{print;a=0}a' file
和@fedorqui的awk '/abc/{a=1} a; /mno/{a=0}' file
都不适合我。 br />最后,我设法通过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
中付出了更多的努力,也打印了pattern2行,即package BBB
ddd
eee
package CCC
< />
评论
如果要打印包括图案在内的所有内容,则可以使用awk'/ abc / {a = 1} / mno / {print; a = 0} a'文件。
–scai
13年7月7日在8:08
是的,@ scai!甚至awk'/ abc / {a = 1} a; / mno / {a = 0}'文件-为此,在/ mno /之前放置一个条件,使它在设置a = 0之前将行评估为true(并打印)。这样我们可以避免写印刷品。
– fedorqui'停止伤害'
13年7月7日在9:43
@scai @fedorqui对于包括模式输出,您可以执行awk'/ abc /,/ mno /'文件
–乔特尼
2013年12月4日6:44
@hkasera awk'/ abc / {flag = 1} / mno / {flag = 0} flag'文件应为。
– fedorqui'停止伤害'
2014年12月11日在8:54
@EirNym是一个很奇怪的场景,可以用非常不同的方式处理:您要打印哪些行?可能是awk'标志; / PAT1 / {flag = 1; next} / PAT1 / {flag = 0}”文件生成。
– fedorqui'停止伤害'
17年4月24日在8:28