Bash脚本问题:管道传递含括号的文件路径变量报错如何解决?
脚本问题修复与优化方案
一、正确传递变量的修复方法
原错误是因为文件名包含(和)这类Shell特殊字符,直接将$0拼入system()命令时,Shell会把它们当成语法符号解析。解决方法是对文件名做转义处理,让Shell将其视为普通字符串:
#!/bin/bash ls /output/analysed/out/reports/sourceDir/sourceFile_\(1.23\)_reviewed.tsv | awk -F'/' '{printf "rsync -avrP %q %q\n", $0, $6"_identifier.tsv"}' | sh
核心改动:
- 用
printf的%q格式符自动转义文件名中的特殊字符,确保Shell能正确识别完整文件名 - 将awk生成的命令通过管道交给
sh执行,替代原有的system()调用,逻辑更清晰
二、更优实现方案
依赖ls解析文件名容易在特殊字符场景下出问题,改用find+Shell循环的方式更可靠、易维护:
#!/bin/bash find /output/analysed/out/reports/sourceDir -name 'sourceFile_(1.23)_reviewed.tsv' -type f | while read -r src_file; do # 提取路径中的第6个目录名(用cut实现) dir_name=$(echo "$src_file" | cut -d'/' -f6) # 若用bash参数扩展,无需外部命令,效率更高: # dir_name=${src_file%/*/*/*/*/*} # dir_name=${dir_name##*/} # 复制文件并按目录名重命名,注意用双引号包裹变量 rsync -avP "$src_file" "${dir_name}_identifier.tsv" done
优化点:
- 用
find精准定位目标文件,避免ls的输出解析隐患 - 用
while read循环处理每个文件路径,天然支持带特殊字符的文件名 - 去掉
rsync的-r参数(复制单个文件无需递归),简化命令 - 提供两种目录名提取方式,参数扩展方式更高效
内容的提问来源于stack exchange,提问作者Jared
相关产品推荐
相关产品推荐

