sed上下文地址匹配异常:为何打印整个文件?
问题:sed范围匹配打印整个文件的原因及解决方法
我有一个名为file.txt的文本文件,内容如下:
lord blue bird The sky reptile lorwood wood
我尝试使用sed命令结合基本正则表达式,打印“lord”到“reptile”之间的行,命令为:
$ sed -n '/^lor/,/^rep/p' file.txt
但结果却像cat命令一样打印了整个文件,请问这是为什么?我使用的sed版本信息如下:
$ sed --version sed (GNU sed) 4.8 Packaged by Debian Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Written by Jay Fenlason, Tom Lord, Ken Pizzini, Paolo Bonzini, Jim Meyering, and Assaf Gordon. This sed program was built with SELinux support. SELinux is disabled on this system. GNU sed home page: <https://www.gnu.org/software/sed/>. General help using GNU software: <https://www.gnu.org/gethelp/>. E-mail bug reports to: <bug-sed@gnu.org>.
原因分析
你使用的/^lor/,/^rep/p是sed的范围匹配模式,它的工作逻辑是:
- 找到第一个匹配
^lor的行(第一行lord),激活打印模式; - 持续打印直到找到匹配
^rep的行(第五行reptile),此时关闭打印模式; - 但第六行
lorwood同样匹配^lor,会再次激活打印模式,而文件后续没有匹配^rep的行来关闭这个模式,所以从第六行到文件末尾的所有行都会被打印,最终输出整个文件内容。
解决方法
要实现仅打印lord到reptile的范围,需要精确匹配避免重复触发:
方法1:精确匹配整行
如果需求是匹配整行完全等于lord和reptile,用行首行尾锚点^$限定:
sed -n '/^lord$/,/^reptile$/p' file.txt
这样只有整行完全匹配的行才会触发范围的开始和结束,不会匹配到lorwood。
方法2:匹配完整单词
如果需求是匹配以lor开头的完整单词(而非行首的lor字符),使用单词边界\<:
sed -n '/\<lord\>/,/\<reptile\>/p' file.txt
\<表示单词的起始边界,lorwood中的lor不是独立单词,因此不会被匹配。
方法3:分支控制避免重复触发
若必须使用行首匹配,可通过sed的标记和分支控制确保仅触发一次范围:
sed -n '/^lord$/{:a;N;/^reptile$/ba;p}' file.txt
该命令找到lord后开始读取后续行,直到匹配到reptile才打印整个范围,不会被后续的lorwood干扰。
内容的提问来源于stack exchange,提问作者gambarimas87
相关产品推荐
相关产品推荐

