Linux下批量处理多目录同名VCF文件时生成空文件的问题求助
Linux下批量处理多目录同名VCF文件时生成空文件的问题求助
我来帮你排查下问题,你单个目录处理的逻辑是对的,但批量遍历目录时踩了两个小坑,导致生成空文件:
1. 管道让cd白忙活了
你写的cd /user/xxxxxxxx/$i |这里用了管道,这会创建一个子shell来执行cd——也就是说,目录切换只在这个子shell里生效,后面的find命令还是在你原来的工作目录跑,根本没进到目标$i目录里。这就导致find要么找不到正确的File.vcf,要么找到的是其他位置不符合要求的文件,最后生成的cleaned文件自然是空的。
2. 文件名切割逻辑在目录切换后失效
假设你真的进到目标目录了,find找到的$file会是./File.vcf这种相对路径,这时候用cut -d'_' -f2分割的话,因为路径里没有下划线,会得到空字符串,生成的文件名是_cleaned.vcf——如果这个文件之前存在就会被清空覆盖,新文件就是空的。
修正后的两种方案
给你两种靠谱的修正思路,选哪个都行:
方案一:正确切换目录处理
把cd和后续命令用分号/换行分隔,别用管道,同时用目录名来生成cleaned文件名(毕竟你是按目录批量处理,每个目录对应一个结果文件):
# 把这里的目录名换成你的7个目录,用空格分开 for i in "dir1" "dir2" "dir3" "dir4" "dir5" "dir6" "dir7"; do # 切换目录,如果失败就跳过这个目录,避免脚本中断 cd "/user/xxxxxxxx/$i" || continue find . -type f -name "File.vcf" -print0 | while IFS= read -r -d '' file; do # 用当前遍历的目录名作为cleaned文件的前缀,避免切割路径的麻烦 awk 'substr($0,1,3)=="chr"' "$file" > "${i}_cleaned.vcf" done # 切回原来的工作目录,不影响下一次循环 cd - > /dev/null done
方案二:不切换目录,直接指定路径
如果你不想来回切换目录,可以直接让find遍历目标目录,然后从路径里提取目录名:
# 直接列出所有目标目录的完整路径,或者用通配符比如/user/xxxxxxxx/dir* for dir in /user/xxxxxxxx/dir1 /user/xxxxxxxx/dir2 ...; do # 只找当前目录下的File.vcf,不递归子目录(如果需要递归就去掉-maxdepth 1) find "$dir" -maxdepth 1 -type f -name "File.vcf" -print0 | while IFS= read -r -d '' file; do # 提取目录的最后一级名称 dir_name=$(basename "$dir") awk 'substr($0,1,3)=="chr"' "$file" > "${dir_name}_cleaned.vcf" done done
几个小提醒
- 处理文件路径时,优先用
basename、dirname这类专门工具,比cut分割靠谱多了,尤其是路径里有特殊字符或者下划线位置不确定的时候。 - 给
cd加上|| continue,万一某个目录不存在或者权限不够,脚本会跳过它继续处理其他目录,不会直接报错中断。 - 记得给变量加双引号(比如
"$file"),避免文件名里有空格或者特殊字符导致awk出错。
你可以先拿一个目录测试下,确认生成的cleaned文件内容正确后,再批量处理所有7个目录~
备注:内容来源于stack exchange,提问作者user20330606
相关产品推荐
相关产品推荐

