Bash 为什么不是';这段代码不能获取文件名吗?

Bash 为什么不是';这段代码不能获取文件名吗?,bash,Bash,在包含许多文件的文件夹中,如下所示: filtered_bcbc8273.bam filtered_a8626340.bam filtered_fae86ca5.bam 我想使用samtools(最后添加了.bam)对它们进行排序,并将排序后的文件保存为: sorted_bcbc8273.bam sorted_a8626340.bam sorted_fae86ca5.bam 但我的输出是: sorted_.bam 这里怎么了 cd /work/folder/ for l in *; do

在包含许多文件的文件夹中,如下所示:

filtered_bcbc8273.bam
filtered_a8626340.bam
filtered_fae86ca5.bam
我想使用samtools(最后添加了.bam)对它们进行排序,并将排序后的文件保存为:

sorted_bcbc8273.bam
sorted_a8626340.bam
sorted_fae86ca5.bam
但我的输出是:

sorted_.bam
这里怎么了

cd /work/folder/
for l in *; do
name=$(echo "$l" | cut -d "_" -f 2 | cut -d "." -f 1)
samtools sort -n /work/folder/filtered_$name\.bam /work/folder/sorted/sorted_$name\
cd ..
done

为了使其行为更加可靠,我建议将其改写如下:

cd /work/folder
for f in filtered_*.bam; do
  [[ -e $f ]] || continue  # skip any file that doesn't exist (ie. glob failed)
  id=${f#filtered_}                  # strip prefix from filename
  id=${id%.bam}                      # strip suffix from filename
  samtools sort -n "$f" "sorted_$id" # run tool
done
优点:

  • 使用更具体的glob表达式(
    filtered.*.bam
    )可以确保名称满足我们的期望,因此不会因为迭代与预期模式不匹配的文件而失败
  • 使用参数扩展来修剪已知的前缀和后缀,可以防止
    cut
    操作删除除这些已知前缀或后缀以外的任何内容,从而使操作更加可靠
  • 使用shell的内置字符串操作比分叉子shell来启动外部工具更快(在内部循环中这样做时;外部工具在整个输入流中只运行一次时效率更高)
最后,在循环中使用
cd..
可以确保在工作目录到达根目录之前,每个循环迭代都将在不同的目录中运行


有关bash的字符串操作原语的更多详细信息,或有关所用原语和其他类似原语的重点说明,请参见。

为了使其行为更可靠,我建议将其改写如下:

cd /work/folder
for f in filtered_*.bam; do
  [[ -e $f ]] || continue  # skip any file that doesn't exist (ie. glob failed)
  id=${f#filtered_}                  # strip prefix from filename
  id=${id%.bam}                      # strip suffix from filename
  samtools sort -n "$f" "sorted_$id" # run tool
done
优点:

  • 使用更具体的glob表达式(
    filtered.*.bam
    )可以确保名称满足我们的期望,因此不会因为迭代与预期模式不匹配的文件而失败
  • 使用参数扩展来修剪已知的前缀和后缀,可以防止
    cut
    操作删除除这些已知前缀或后缀以外的任何内容,从而使操作更加可靠
  • 使用shell的内置字符串操作比分叉子shell来启动外部工具更快(在内部循环中这样做时;外部工具在整个输入流中只运行一次时效率更高)
最后,在循环中使用
cd..
可以确保在工作目录到达根目录之前,每个循环迭代都将在不同的目录中运行


有关bash的字符串操作原语的更多详细信息,或有关所使用的原语和其他类似原语的重点说明,请参见。

如果在循环中放入
cd..
,则除了第一项之外,您肯定会将每一项都放在错误的目录中。@CharlesDuffy:没错,但是循环中的任何内容实际上都不取决于是否在正确的目录中。@ruakh,如果不知道
samtools
及其语义,我就不能说这是否正确。(处理一个文件可以包括其他文件吗?searth路径是什么样子的?等等)。如果在循环中放入
cd..
,那么除了第一个项目之外,您肯定每个项目都位于错误的目录中。@CharlesDuffy:没错,但循环中的任何内容实际上都不取决于是否位于正确的目录中。@ruakh,如果不知道
samtools
及其语义,我就无法判断这是否正确。(处理文件是否可以包括其他文件?searth路径是什么样子的?等等)。