为什么grep lookahead匹配时会重复获取两次相同值?
问题描述
需求为通过grep的正则匹配功能,定位文件中带冒号的目标关键词后,提取紧跟在关键词后的第一个单词,赋值给shell变量。
示例匹配行格式:TARGETWORD: NEXTWORD
最初使用的赋值命令:
set myVariable = `cat File.txt | grep -oP '(?<=TARGETWORD: )[^ ]*'`
验证变量值的命令:
echo $myVariable
- 预期输出:
NEXTWORD - 实际输出:
NEXTWORD NEXTWORD,提取到的内容重复两次,中间以空格分隔。
问题原因
出现重复值有两个常见核心原因:
- 目标文件
File.txt中存在至少两行符合正则匹配规则的内容,grep -o会输出所有匹配到的结果,命令替换会将输出中的换行符替换为空格,最终赋值时就会出现多个值空格分隔的情况。 - 若运行环境是Bash/Zsh等POSIX标准Shell,错误使用
set命令给普通变量赋值:这类Shell中set的作用是设置Shell运行选项或位置参数,并非定义普通变量,语法误用会导致变量赋值逻辑异常。
另外命令中多余的cat管道属于无意义的子进程调用,grep本身支持直接传入文件路径参数,不需要通过管道接收cat的输出。
修复方案
- 先单独执行grep命令,确认实际匹配到的结果数量:
grep -oP '(?<=TARGETWORD: )[^ ]*' File.txt
- 给grep添加
-m 1参数,指定匹配到第一个符合规则的结果后就停止扫描文件,避免多匹配导致的重复值。 - 根据使用的Shell选择正确的赋值语法:
- 如果使用Csh/Tcsh,使用set赋值的写法调整为:
set myVariable = `grep -m 1 -oP '(?<=TARGETWORD: )[^ ]*' File.txt`
- 如果使用Bash/Zsh/Sh等POSIX系Shell,去掉错误的set关键字,使用$()做命令替换即可:
myVariable=$(grep -m 1 -oP '(?<=TARGETWORD: )[^ ]*' File.txt)
调整后再执行echo $myVariable就只会输出单个NEXTWORD,符合预期。
内容的提问来源于stack exchange,提问作者A.JD
相关产品推荐
相关产品推荐

