如何用Bash脚本遍历目录,生成指定格式的文件名对应列表?
修正Bash脚本实现指定目录文件格式转换列表生成
你的思路方向是对的,但原脚本有几个关键细节处理不当,导致输出格式不符合预期。我来帮你调整并解释问题所在:
原脚本的核心问题
- 使用
${fastq_names[*]}会把数组里的所有文件名用空格拼接成一个字符串,无法实现逐个文件的配对输出 - 最后的
printf语句把所有前缀名输出成一行、所有.fna后缀名输出成一行,完全不符合每行一对的要求 - 没有处理“目录下没有.fastq文件”的边界情况,会导致错误输出
*.fastq这类无效字符串
修正后的脚本
# 遍历当前目录下所有以P开头的子目录(P*/确保只匹配目录,避免误匹配文件) for dir in P*/; do # 进入目标子目录,隐藏pushd的默认输出;如果进入失败则跳过该目录 pushd "$dir" > /dev/null || continue # 定义输出文件路径:上级目录下的「目录名_names.txt」,${dir%/}去掉目录名末尾的斜杠 output_file="../${dir%/}_names.txt" # 先清空输出文件(避免多次运行时内容累加) > "$output_file" # 遍历当前目录下所有.fastq格式的文件 for fastq_file in *.fastq; do # 检查是否真的存在该文件(防止目录下无.fastq时,*.fastq作为字符串被处理) [[ -f "$fastq_file" ]] || continue # 提取去掉.fastq扩展名的基础文件名 base_name="${fastq_file%.fastq}" # 写入一行:基础文件名 + 基础文件名.fna echo "$base_name $base_name.fna" >> "$output_file" done # 退出当前子目录,隐藏popd的默认输出 popd > /dev/null done
关键改动说明
- 目录遍历:用
P*/直接匹配以P开头的子目录,比存数组的写法更简洁可靠 - 错误处理:
pushd ... || continue确保如果目录无法进入(比如权限问题),脚本会跳过该目录继续执行,不会中断 - 文件处理:逐个遍历
.fastq文件,配合[[ -f "$fastq_file" ]]判断,避免无匹配文件时的错误输出 - 输出格式:逐行生成
基础名 基础名.fna的格式,完全符合你的需求 - 输出文件初始化:
> "$output_file"确保每次运行都会清空旧文件,不会出现内容累加的问题
效果验证
假设你有子目录P_sample,里面包含ERR163030.fastq和ERR163031.fastq,运行脚本后,上级目录会生成P_sample_names.txt,内容如下:
ERR163030 ERR163030.fna ERR163031 ERR163031.fna
内容的提问来源于stack exchange,提问作者kath.g
相关产品推荐
相关产品推荐

