编辑:在 @john1024 的精彩回应之后,我想知道是否可以:

编辑:在 @john1024 的精彩回应之后,我想知道是否可以:

prova.txt我有一个这样的文件:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

extra1
extra2
bla

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

extra2
bla
bla

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

我需要从“开始抓取这里”到第一个空行。输出应该是这样的:

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4

Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

正如您所看到的,“开始抓取此处”之后的行是随机的,因此 -A -B grep 标志不起作用:

cat prova.txt | grep "Start to grab from here" -A 15 | grep -B 15 "^$" > output.txt

你能帮我找到一种方法来捕获将被抓取的第一行(如“从这里开始抓取”),直到出现空行。我无法预测“从这里开始抓取”后会有多少条随机线。

任何 UNIX 兼容的解决方案都是值得赞赏的(grep、sed、awk 比 perl 或类似的更好)。

编辑:在 @john1024 的精彩回应之后,我想知道是否可以:

1°对块进行排序(根据从这里开始抓取:1然后1然后2)

2° 删除 4 条(按字母顺序随机)行 fix1,fix2,fix3,fix4 但始终是 4

3° 最终删除随机重复项,例如 sort -u 命令

最终输出应该是这样的:

# fix lines removed - match 1 first time
Start to grab from here: 1
random1
random2
random3
random4

#fix lines removed - match 1 second time
Start to grab from here: 1
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

或者

# fix lines removed - match 1 first time and the second too
Start to grab from here: 1
random1
random2
random3
random4
#random1 removed cause is a dupe
random22131

#fix lines removed - match 2 that comes after 1
Start to grab from here: 2
random1546
random2561

第二个输出比第一个输出更好。还需要一些其他的 Unix 命令魔法。

答案1

使用 awk

尝试:

$ awk '/Start to grab/,/^$/' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

/Start to grab/,/^$/定义一个范围。它以任何匹配的行开始,并以随后的Start to grab第一个空行 结束。^$

使用 sed

具有非常相似的逻辑:

$ sed -n '/Start to grab/,/^$/p' prova.txt
Start to grab from here: 1
random1
random2
random3
random4

Start to grab from here: 2
random1546
random2561

Start to grab from here: 3
random45
random22131

-n告诉 sed 不要打印任何内容,除非我们明确要求它打印。 /Start to grab/,/^$/p告诉它打印由 定义的范围内的任何行/Start to grab/,/^$/

答案2

我发布了一个替代解决方案,因为它可能对某些人的用例有用。该解决方案并不完全符合规定的要求,有关最佳解决方案,请参阅@John1024 的答案。

您可以使用 awk 将记录分隔符设置为空字符串,awk 会将它们解释为空白换行符:

$ awk '/Start/' RS= prova.txt 
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random2
random3
random4
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561
Start to grab from here: 1
fix1
fix2
fix3
fix4
random1
random22131

此版本不保留输出中的空白换行符。它还会显示比赛前的上下文(如果存在)。当 grep 查找文件中的某些内容并且您想要查看它所属的换行符分隔块时,此行为非常有用,例如:

$ awk '/random1546/' RS= prova.txt 
Start to grab from here: 2
fix1
fix2
fix3
fix4
random1546
random2561

例如,我发现这在查找ini文件中的内容时很有用。

相关内容