Eru*_*aki 0 grep sed text-processing files
我需要解析一个文件,我希望在两个特定行之间打印一段数据。从“范围开始”到“范围结束”,但前提是“范围结束”存在。
如果源文件是:
[This is the start] of some data
this is information
this is more information
This is does not contain the ending required
[This is the start] of some other data
this is info I want
this is info I want
[This is the ending I was looking for]
Run Code Online (Sandbox Code Playgroud)
它应该打印:
[This is the start] of some other data
this is info I want
this is info I want
[This is the ending I was looking for]
Run Code Online (Sandbox Code Playgroud)
使用 grep 我已经能够找到我需要的数据并向上打印,但只能通过固定数量的行。
鉴于数据的行数不是恒定的,有没有一种方法可以使用 grep 或 sed,从结束行开始查找给定字符串的下一次出现并捕获我想要的特定范围?
数据段的“范围开始”应该与“范围开始”和“范围结束”点之间的任何数据一起打印,“范围结束”匹配决定是否应该打印整个范围的行. 如果范围(数据段)没有指定的结尾,则不应打印。如果多个段有一个终点,那么所有包含一个终点的段都应该被打印出来。不存在输入文件的结尾没有开头或多个结尾到单个开头的情况。
打印两个模式之间(和包括)的行并不能解决我的问题,因为它开始在匹配的第一行打印并一直打印,直到找到第一个结束段。我只需要打印包含指定结束语句的段。
使用sed
:
$ sed -n '/This is the start/{h;d;}; H; /This is the ending/{x;p;}' file
[This is the start] of some other data
this is info I want
this is info I want
[This is the ending I was looking for]
Run Code Online (Sandbox Code Playgroud)
注释sed
脚本:
/This is the start/{ # We have found a start
h; # Overwrite the hold space with it
d; # Delete from pattern space, start next cycle
};
H; # Append all other lines to the hold space
/This is the ending/{ # We have found an ending
x; # Swap pattern space with hold space
p; # Print pattern space
};
Run Code Online (Sandbox Code Playgroud)
脚本所做的是将所有行保存到“保持空间”(中的通用缓冲区sed
)中,但是一旦我们找到“开始行”,我们就会重置该空间。当找到“结束行”时,打印保存的数据。
如果在“起点线”之前找到“终点线”,并且可能发现两个“终点线”中间没有“起点线”,则这会中断。
一个awk
与上述sed
程序经历相同过程的程序:
$ awk '/This is the start/ { hold = $0; next }
{ hold = hold ORS $0 }
/This is the ending/ { print hold }' file
Run Code Online (Sandbox Code Playgroud)
(与上面相同的输出)