如何用sed或awk命令打印两匹配模式间内容(第二个模式多次出现)
解决sed匹配到最后一个指定模式的问题
首先得说清楚你遇到的核心问题:sed的区间匹配/Have/,/day/是非贪婪的单行匹配——在同一句话里,它找到第一个Have后,会立刻停在第一个出现的day上,所以只输出到第一个day就结束了。
要匹配到最后一个day,我们可以利用sed的贪婪正则特性来实现,或者用awk更直观地处理。这里给你两种可行的方案:
方案1:用sed的贪婪正则替换
因为sed的正则默认是贪婪匹配(会尽可能匹配最长的内容),我们可以直接定位从Have开始到最后一个day;的部分:
sed -n 's/.*\(Have.*day;\).*/\1/p' F1
命令解释:
.*:匹配开头到Have之前的所有内容(贪婪吃掉前面的无关部分)\(Have.*day;\):捕获从Have开始到最后一个day;的所有内容(.*会贪婪匹配到最后一个day;)\1:输出我们捕获的目标内容-n和p:只打印处理后的匹配行
执行这个命令后,输出就是你想要的:
Have a nice day; see you again the next day;
方案2:用awk精准截取(更易读)
如果觉得sed的正则有点绕,awk的match函数可以更直观地定位匹配区间:
awk '{match($0, /Have.*day;/); print substr($0, RSTART, RLENGTH)}' F1
命令解释:
match($0, /Have.*day;/):在当前行中匹配从Have到最后一个day;的最长字符串RSTART:匹配到的内容的起始位置RLENGTH:匹配到的内容的长度substr:根据起始位置和长度截取并打印目标内容
这个命令的输出结果和方案1完全一致。
内容的提问来源于stack exchange,提问作者MissNaz
相关产品推荐
相关产品推荐

