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
디렉터리와 하나의 중첩 수준만 나열됩니다.
루프는 다음과 같습니다:
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 \;