如何转到每个目录并对特定文件执行命令?

sta*_*ner 3 bash

如何编写一个 bash 脚本,该脚本遍历 parent_directory 中的每个目录并对特定文件执行命令。

目录结构如下:

Parent_dir/
  dir1/
   acc.bam
  dir2/
   acc.bam
  dir3/
   acc.bam
... around 30 directories
Run Code Online (Sandbox Code Playgroud)

这是我要使用的命令:

java8 -jar /picard.jar CollectRnaSeqMetrics REF_FLAT=/refFlathuman.refflat STRAND_SPECIFICITY=NONE I=acc.bam O=output
Run Code Online (Sandbox Code Playgroud)

Tob*_*ght 10

通常的成语是

for d in Parent_dir/*/
do
     (cd "$d" && $command)
done
Run Code Online (Sandbox Code Playgroud)

该for循环直接在Parent_dir. 对于这些目录中的每一个,都会产生一个子 shell;在子 shell 中,我们尝试切换到该目录(这可能会失败,例如,如果我们没有足够的权限),如果成功,则执行命令。不管我们成功与否,这cd对父shell 没有影响,所以我们不必担心在那里出现错误的地方。


如果你想让它更健壮,你可以

    (cd "$d" && test -r acc.bam &&  $command)
Run Code Online (Sandbox Code Playgroud)

以确保acc.bam在该目录中存在并且可读。您还可以添加test -w .以避免尝试在不可写的目录中运行命令。


PS 以上都不是 Bash 特有的;您可以非常方便地使用 /bin/sh 。


asm*_*ean 3

使用 . 循环遍历父目录中的文件for FILE in *; do ...; done。如果该文件是一个目录,cd则进入该目录,执行您的命令,然后cd ...

cd $parent_directory
for FILE in *; do
    if [ -d "$FILE" ]; then
        cd "$FILE"
        java8 -jar /picard.jar CollectRnaSeqMetrics REF_FLAT=/refFlathuman.refflat STRAND_SPECIFICITY=NONE I=acc.bam O=output
        cd ..
    fi
done
Run Code Online (Sandbox Code Playgroud)

您还可以在命令中使用文件名来避免更改目录,例如I="$FILE/acc.bam".