Bash for循环中目录切换与输出路径设置技术咨询
在Bash循环中处理目录路径与文件匹配的问题
看起来你在处理Bash循环里的路径匹配和文件输出时遇到了几个小问题,我来一步步帮你解决:
一、先解决你现有代码的--in2参数为空的问题
你当前的代码里,--in2 "./test/*out/count.txt" 这部分有两个核心问题:
- 双引号会阻止通配符
*展开:Bash在双引号内不会解析*,所以这个参数会被当成字面量字符串./test/*out/count.txt,而非实际匹配到的count.txt文件。 - 每个
$f对应的count.txt应该是同目录下的:假设$f是./test/sample1out/file.coords,那对应的count.txt应该是./test/sample1out/count.txt,而非全局匹配所有out目录的count.txt。
修改后的代码可以这样写,用dirname提取$f的目录路径,再拼接count.txt:
for f in ./test/*out/*coords; do # 提取当前f所在的目录 out_dir=$(dirname "$f") ./test/sort.pl --in1 "$f" --in2 "${out_dir}/count.txt" --out "${f/.coords/.sorted}" done
这样--in2就能正确指向每个$f所在目录下的count.txt文件了。
二、将文件保存到指定目录(比如./test/)
如果想把输出文件统一放到./test/目录,而非和输入文件同目录,只需要修改--out的路径:
for f in ./test/*out/*coords; do out_dir=$(dirname "$f") # 提取输入文件的文件名(去掉路径和.coords后缀) filename=$(basename "$f" .coords) # 输出到./test/目录下,文件名加上.sorted后缀 ./test/sort.pl --in1 "$f" --in2 "${out_dir}/count.txt" --out "./test/${filename}.sorted" done
这里用basename命令提取纯文件名部分,再拼接./test/路径,就能把所有输出文件集中放到指定目录里。
三、遍历所有Sample文件夹的实现
假设你的Sample文件夹是类似./Sample1/、./Sample2/这样的命名,或者在某个特定目录下,比如./test/Sample*,可以分两种情况实现:
情况1:遍历当前目录下所有Sample开头的文件夹
for sample_dir in ./Sample*/; do # 检查是否为目录(避免匹配到同名文件) if [ -d "$sample_dir" ]; then # 处理每个Sample文件夹里的coords文件 for f in "${sample_dir}"*coords; do # 提取文件名并设置输出路径 filename=$(basename "$f" .coords) out_file="./test/${filename}.sorted" ./test/sort.pl --in1 "$f" --in2 "${sample_dir}count.txt" --out "$out_file" done fi done
情况2:遍历./test/目录下的所有Sample文件夹
如果Sample文件夹都在./test/下,只需把循环的匹配路径改成./test/Sample*/即可:
for sample_dir in ./test/Sample*/; do # 后续逻辑和上面一致 done
注意在路径末尾加/,可以确保只匹配目录,不会误匹配到同名文件。
额外小提示
- 处理路径时一定要用双引号包裹变量,避免文件名包含空格或特殊字符导致脚本出错。
- 可以先通过
echo命令测试路径是否正确,比如在执行sort.pl前先打印参数:
确认路径无误后再执行实际脚本。echo "Debug: in1=$f, in2=${out_dir}/count.txt, out=${f/.coords/.sorted}"
内容的提问来源于stack exchange,提问作者user6.9mand1
相关产品推荐
相关产品推荐

