在Bash中尝试将正则匹配结果存入变量失败求助
解决Bash中管道结果存入变量为空的问题
我来帮你搞定这个问题!你的问题出在Bash变量赋值和管道的结合方式上,咱们一步步拆解:
为什么原代码会失败?
你写的这段代码:
for filename in ./unsent_xmls/*.xml; do package=$filename | perl -lne 'print $& if /(\d{4})(?=-)/' echo $package done
这里的核心错误是:package=$filename | perl ...的执行逻辑是先完成package=$filename的赋值(这个操作本身没有任何输出),然后把这个空输出传给perl命令。perl没有拿到文件名作为输入,自然输出为空,最终package变量也就没有被正确赋值。
正确的写法:用命令替换捕获输出
要把管道命令的结果存入变量,你需要用命令替换($()语法,推荐使用,比反引号可读性更好),把整个生成输出的命令包裹起来。修改后的代码如下:
for filename in ./unsent_xmls/*.xml; do # 用$()捕获perl命令的输出,赋值给package package=$(echo "$filename" | perl -lne 'print $& if /(\d{4})(?=-)/') # 输出变量内容 echo "$package" done
注意这里给$filename加上了双引号,避免文件名包含空格、特殊字符时出现解析错误。
更高效的替代方案:用Bash内置正则匹配
其实不需要调用外部的perl命令,Bash本身就支持正则表达式匹配,这样不需要启动额外进程,性能更优。写法如下:
for filename in ./unsent_xmls/*.xml; do # 用Bash内置正则匹配捕获四位数字(后面跟-) if [[ $filename =~ ([0-9]{4})- ]]; then # BASH_REMATCH[1]对应正则中第一个括号捕获的内容 package=${BASH_REMATCH[1]} echo "$package" fi done
内容的提问来源于stack exchange,提问作者GeneralBear
相关产品推荐
相关产品推荐

