parent_directoryの各ディレクトリを繰り返し、特定のファイルに対してコマンドを実行するbashスクリプトを作成する方法。
ディレクトリ構造は次のとおりです。
Parent_dir/
dir1/
acc.bam
dir2/
acc.bam
dir3/
acc.bam
... around 30 directories
これが私が使用したいコマンドです:
java8 -jar /picard.jar CollectRnaSeqMetrics REF_FLAT=/refFlathuman.refflat STRAND_SPECIFICITY=NONE I=acc.bam O=output
答え1
一般的な慣用語は
for d in Parent_dir/*/
do
(cd "$d" && $command)
done
ループfor
は、.txtファイルの各ディレクトリに対して一度だけ直接実行されますParent_dir
。各ディレクトリに対してサブシェルが作成されます。サブシェルからそのディレクトリに変更しようとします(たとえば、十分な権限がないと失敗する可能性があります)、成功した場合はコマンドを実行します。成功するかどうかはcd
親シェルに影響を与えないため、間違った場所を心配する必要はありません。
もっと頑丈にしたいなら
(cd "$d" && test -r acc.bam && $command)
acc.bam
ディレクトリが存在し、読み取り可能であることを確認してください。test -w .
書き込み不可能なディレクトリでコマンドを実行したくない場合は、を追加することもできます。
PS上記のどれもBashに限定されません。 /bin/sh はかなり簡単に使用できます。
答え2
.を使用して親ディレクトリのファイルを繰り返します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
ディレクトリの変更を避けるために、コマンドにファイル名を使用することもできますI="$FILE/acc.bam"
。
答え3
あなたがしなければならないのは、parent_directoryの各ディレクトリに行き、javaコマンドを実行することだけです。 parent_directoryに戻るには、次のようにします。
cd ..
parent_directory のディレクトリのリストを取得するには、次のものを使用できます。
find -mindepth 1 -maxdepth 2 -type d
ディレクトリと1つのネストされたレベルのみが一覧表示されます。
ループは次のとおりです。
cmd="java8 -jar /picard.jar CollectRnaSeqMetrics REF_FLAT=/refFlathuman.refflat STRAND_SPECIFICITY=NONE I=acc.bam O=output"
for path in `find -mindepth 1 -maxdepth 2 -type d`
do
cd "$path"
$cmd
cd ..
done
Javaコマンドは、スクリプトを読みやすくするために別々の変数に配置されます。
答え4
(少なくともBSD、GNU)find
実装をサポートすることによって:-execdir
sfind
find ParentDir -name acc.bam -execdir \
java8 -jar /picard.jar CollectRnaSeqMetrics \
REF_FLAT=/refFlathuman.refflat \
STRAND_SPECIFICITY=NONE I=acc.bam O=output \;