![for 循环遍历多个目录和多个文件](https://linux22.com/image/222091/for%20%E5%BE%AA%E7%8E%AF%E9%81%8D%E5%8E%86%E5%A4%9A%E4%B8%AA%E7%9B%AE%E5%BD%95%E5%92%8C%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我想检查每个 .bam 文件是否都附带 .bai 文件。因此,如果 clean_xyz_1.sorted.bam 存在,clean_xyx_1.sorted.bam.bai 也应该存在。每个文件的中间都有一个变量字符串 (xyz)。我想检查多个文件夹以确保这两个文件都存在。如果这两个文件都不存在,我想运行一个命令。但是,我无法检查多个目录中的两个文件。这是我尝试过的:
dirs=(*/)
clean="clean_"
sorted="_1.sorted.bam"
for i in "$dirs"/"$clean"*"$sorted"*; do
if [[ ! -e "$i".bai ]]; then
samtools index "$i"
fi
done
该命令运行良好并创建一个“.bai”文件。但是,它只打开第一个目录。有没有办法扩展所有目录?
答案1
dir=(*/)
在当前工作目录中创建一个目录数组,要迭代您应该使用的数组,${dir[@]}
而不是$dir
仅打印第一个元素。
"$dirs"/"$clean"*"$sorted"*
也会匹配.bai
文件。这可能是不需要的行为。因此我建议使用*/"$clean"*"$sorted"
for 循环的 glob。
因此我提出这个改变
shopt -s nullglob
clean="clean_"
sorted="_1.sorted.bam"
for i in */"$clean"*"$sorted"; do
if [[ ! -e "$i".bai ]]; then
samtools index "$i"
fi
done
答案2
有了zsh
,你会这样做:
dirs=( *(N/) )
prefix=clean_
suffix=_1.sorted.bam
for file ( $^dirs/$prefix*$suffix(N) )
[[ -e $file.bai ]] || samtools index $file
答案3
通过dir1
, dir2
, ... 搜索所有文件,打印应该存在但缺失的文件.bam
的名称:.bai
find dir1 dir2 ... -type f -name '*.bam' -print | \
while read name ; do
bai=${name%.bam}.bai
[ -f "$bai" ] || printf "missing %s\n" "$bai"
done
这假设您没有包含换行符的路径,因此每行find
输出一个完整的.bam
路径名。