我遇到了以下问题,并没有找到解决方案,也没有为什么awk会以这种奇怪的方式行事。
所以,让我说我在文件中有以下文字:
startcue
This shouldn't be found.
startcue
This is the text I want to find.
endcue
startcue
This shouldn't be found either.
我想找到线条" startcue","这是我想找的文字。"和" endcue"。
我天真地认为通过awk' / startcue /,/ endcue /'进行简单的范围搜索。会这样做,但这打印出整个文件。我想awk以某种方式找到了第一个范围,但是当第三个startcue触发了行的打印时,它会打印所有行直到文件结尾(但是,这对我来说似乎有点奇怪)。
现在问的问题是:我怎么能得到awk才能打印出我想要的线条?也许还有一个额外的问题:任何人都可以解释awk的行为吗?
由于
答案 0 :(得分:3)
$ awk '/startcue/{f=1; buf=""} f{buf = buf $0 RS} /endcue/{printf "%s",buf; f=0}' file
startcue
This is the text I want to find.
endcue
答案 1 :(得分:2)
这是一种简单的方法。
由于数据是用空行分隔的,我将RS
设置为空
这使得awk
可以处理块中的数据
然后找到以startcue
开头并以endcue
awk -v RS="" '/^startcue/ && /endcue$/' file
startcue
This is the text I want to find.
endcue
如果startcue
和endcue
始终是起始行和结束行,并且只在块中出现一次,则应执行以下操作:( PS测试确实表明如果有更多或更多或块中的命中次数较少。如果找到startclue和endcue,则始终打印块。
awk -v RS="" '/startcue/ && /endcue/' file
startcue
This is the text I want to find.
endcue
这也应该有效:
awk -v RS="" '/startcue.*endcue/' file
startcue
This is the text I want to find.
endcue
答案 2 :(得分:1)
要总结问题,您需要从startcue到endcue 的打印行,但如果缺少endcue 则不需要。艾德莫顿的方法很好。这是另一种方法:
$ tac file | awk '/endcue/,/startcue/' | tac
startcue
This is the text I want to find.
endcue
tac file
以相反顺序打印行。 tac
与cat
类似,只是行的顺序相反。
awk '/endcue/,/startcue/'
这将打印从endcue开始并使用startcue完成的所有行。这样做时,不会打印缺少结束的段落。
tac
这会再次反转这些行,以便按正确的顺序返回。
考虑:
awk '/startcue/,/endcue/' file
这会告诉awk
如果找到startcue
则开始打印并继续打印,直到找到endcue
。这正是它在您的文件中所做的。
没有隐含的规则,范围/startcue/,/endcue/
本身不能包含startcue
的多个实例。 awk只是在第一次出现startcue
时开始打印,并一直持续到找到endcue
。