![编辑:在 @john1024 的精彩回应之后,我想知道是否可以:](https://linux22.com/image/97098/%E7%BC%96%E8%BE%91%EF%BC%9A%E5%9C%A8%20%40john1024%20%E7%9A%84%E7%B2%BE%E5%BD%A9%E5%9B%9E%E5%BA%94%E4%B9%8B%E5%90%8E%EF%BC%8C%E6%88%91%E6%83%B3%E7%9F%A5%E9%81%93%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%EF%BC%9A.png)
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
文件中的内容时很有用。