Bash中匹配带序列号的文件名调用Perl脚本失败的解决方法
问题:Bash调用Perl时无法正确匹配带序列号的文件名
场景与问题
公共文件夹下有一批包含数字序列号的文件,示例文件名:
test_S1_L001.sorted.bam abc_S2_L001.sorted.bam cdf_S3_L001.sorted.bam
尝试通过Bash脚本传入序列号(如1、2、3),调用Perl脚本处理对应文件,使用的命令为:
script.pl $mapFolder/*S{$id}_L001.sorted.bam
执行方式为:
mainScript.sh 1 mainScript.sh 2 mainScript.sh 3
但运行时报错:
failed to open "mapFolder/*S1_L001.sorted.bam" for reading: No such file or directory
期望的正确调用应该是传递完整文件名,比如:
script.pl mapFolder/test_S1_L001.sorted.bam
错误原因
Bash中的{}用于大括号扩展,但此处写法错误:变量$id被包裹在{}中时,Bash无法正确解析变量,导致通配符*没有被展开成实际文件名,反而作为字符串直接传给Perl,Perl自然找不到对应的文件。
解决方法
方法1:修正变量引用与通配符写法
去掉多余的大括号,用${id}正确引用变量,同时给路径和变量加上引号避免文件名含空格时出错:
script.pl "$mapFolder"/*S"${id}"_L001.sorted.bam
Bash会先解析${id}为传入的数字,再通过*匹配前缀任意字符的文件,最终将实际文件名传给Perl。
方法2:增加文件存在性校验
为避免匹配到多个文件或无匹配的情况,可先检查文件是否存在:
file_path="$mapFolder"/*S"${id}"_L001.sorted.bam if [ -f "$file_path" ]; then script.pl "$file_path" else echo "错误:未找到对应文件 $file_path" exit 1 fi
方法3:用find命令精准匹配
如果需要更精准的文件查找(比如避免匹配子目录中的文件),可以使用find命令:
file_path=$(find "$mapFolder" -maxdepth 1 -type f -name "*S${id}_L001.sorted.bam") if [ -n "$file_path" ]; then script.pl "$file_path" else echo "错误:未找到对应序列号的文件" exit 1 fi
内容的提问来源于stack exchange,提问作者Callie
相关产品推荐
相关产品推荐

