Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何使用awk打印贪婪的行范围_Regex_Bash_Search_Awk_Range - Fatal编程技术网

Regex 如何使用awk打印贪婪的行范围

Regex 如何使用awk打印贪婪的行范围,regex,bash,search,awk,range,Regex,Bash,Search,Awk,Range,我遇到了以下问题,还没有找到解决方案,也没有找到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
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的行为吗


谢谢

总结一下这个问题,您需要从startcue打印行到endcue,但如果endcue丢失,则不需要。埃德·莫顿的方法很好。以下是另一种方法:

$ tac file | awk '/endcue/,/startcue/' | tac
startcue
This is the text I want to find.
endcue
工作原理 tac文件

这将按相反的顺序打印行。tac和cat一样,只是行的顺序相反

awk'/endcue/,/startcue/'

这将打印从endcue开始到startcue结束的所有行。这样做时,将不会打印缺少尾声的段落

交咨会

这将再次反转这些行,使它们恢复到正确的顺序

awk系列的工作原理 考虑:

 awk '/startcue/,/endcue/' file
这告诉awk在if找到startcue时开始打印,并继续打印直到if找到endcue。这正是它在您的文件中所做的


没有隐含规则表明/startcue/,/endcue/范围本身不能包含多个startcue实例。awk只需在看到第一次出现startcue时开始打印,直到找到endcue为止。

为了总结问题,您需要从startcue到endcue打印行,但如果endcue丢失,则不需要。埃德·莫顿的方法很好。以下是另一种方法:

$ tac file | awk '/endcue/,/startcue/' | tac
startcue
This is the text I want to find.
endcue
工作原理 tac文件

这将按相反的顺序打印行。tac和cat一样,只是行的顺序相反

awk'/endcue/,/startcue/'

这将打印从endcue开始到startcue结束的所有行。这样做时,将不会打印缺少尾声的段落

交咨会

这将再次反转这些行,使它们恢复到正确的顺序

awk系列的工作原理 考虑:

 awk '/startcue/,/endcue/' file
这告诉awk在if找到startcue时开始打印,并继续打印直到if找到endcue。这正是它在您的文件中所做的


没有隐含规则表明/startcue/,/endcue/范围本身不能包含多个startcue实例。awk只需在看到第一次出现startcue时开始打印,直到找到endcue为止。

这里有一个简单的方法。 因为数据是用空行分隔的,所以我将RS设置为nothing。 这使得awk能够处理块中的数据。 然后查找以startcue开始并以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

下面是一个简单的方法。 因为数据是用空行分隔的,所以我将RS设置为nothing。 这使得awk能够处理块中的数据。 然后查找以startcue开始并以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

该范围尽可能多地匹配。第一场比赛是第1行到终点,第二场比赛是到终点的最后一场比赛。所以不应该打印第二个空行。您希望awk如何知道您建议使用的startcue。当你点击一个新的起始行时,你可以手动保留这些行并删除以前保存的行,这样做你想做什么。永远不要使用范围表达式,总是使用一个标志,例如/start/{f=1}f/结束/{f=0}。范围表达式使用于解决琐碎工作的脚本变得非常简短,但随后需要完全重写和/或复制条件,即使是最微小的复杂性也会被引入,正如您所发现的那样。该范围尽可能匹配多次。第一场比赛是第1行到终点,第二场比赛是到终点的最后一场比赛。所以不应该打印第二个空行。您希望awk如何知道您建议使用的startcue。您可以通过手动保留行并在到达新的起始行时删除以前保存的行来执行所需操作。切勿使用范围表达式,始终使用标志,
e、 g./start/{f=1}f/结束/{f=0}。范围表达式使用于解决琐碎工作的脚本变得非常简短,但是,正如您所发现的,即使引入了最微小的复杂性,也需要完全重写和/或复制条件。不过,这正好相反。这将打印具有结束提示但没有开始提示的部分。这也大大低于Ed使用的更直接的非双关语方法。谢谢!这同样有效,但由于Ed提供了一个只有awk的解决方案,我会同意他的观点。不过解释得不错@EtanReisner 1 OP只显示了缺失的尾声,所以,是的,正如这个答案的第一句所说,这个答案只是关于缺失的尾声。有时计算机效率很重要。通常情况下,更重要的是有效利用程序员的时间。由于这段代码很短,不需要定义和更新变量的代码,我相信它符合后面效率的含义。当通用解决方案可用时,根据具体情况定制解决方案通常不是回答问题的最佳方式。尽管如此,我并不是在攻击你的答案,而是在指出一个细节,OP和后来看到这个答案的人可能不会马上意识到这个问题的存在。不过,这正好相反。这将打印具有结束提示但没有开始提示的部分。这也大大低于Ed使用的更直接的非双关语方法。谢谢!这同样有效,但由于Ed提供了一个只有awk的解决方案,我会同意他的观点。不过解释得不错@EtanReisner 1 OP只显示了缺失的尾声,所以,是的,正如这个答案的第一句所说,这个答案只是关于缺失的尾声。有时计算机效率很重要。通常情况下,更重要的是有效利用程序员的时间。由于这段代码很短,不需要定义和更新变量的代码,我相信它符合后面效率的含义。当通用解决方案可用时,根据具体情况定制解决方案通常不是回答问题的最佳方式。我不是在攻击你的答案,而是指出了一个细节,OP和后来看到这个答案的人可能不会立即意识到这里的存在。当然,它初始化一个缓冲区并在找到第一个regexp时设置一个标志,在设置标志时每行添加一个缓冲区,然后打印缓冲区并在找到最后一个regexp时重置标志。我将再次链接到您的,因为看到此模式的其他用法可能有助于人们理解它。当然,它初始化缓冲区并在找到第一个regexp时设置标志,在设置标志时每行添加到缓冲区,然后打印缓冲区并在找到最后一个regexp时重置标志。我将再次链接到您的,因为查看此模式的其他用法可能有助于人们理解它。