하위 디렉터리의 다른 수의 파일에 대한 루프 명령

하위 디렉터리의 다른 수의 파일에 대한 루프 명령

하위 디렉터리에 있는 다양한 수의 파일에 대해 명령을 실행하는 스크립트를 작성하는 방법을 찾으려고 합니다. 72개의 하위 디렉터리가 있는데, 각각에는 다양한 수의 샘플 파일(fastq.gz 파일)이 있고 가장 큰 하위 디렉터리에는 20개의 샘플 파일이 있습니다. 다음 명령을 사용했는데 하위 디렉터리의 파일 수가 20개 미만인 경우 빈 폴더와 파일이 많이 제공됩니다.

#!/bin/sh
TOPHAT_BINARY=/home/alex/tools/tophat-2.1.0.Linux_x86_64/tophat2
GENE_REFERENCE=/home/alex/toxo/ref/genes/ToxoDB-27_TgondiiME49.gff
BOWTIE_INDEX=/home/alex/toxo/ref/bwt/ToxoDB-27_TgondiiME49_Genome
P=10 #use 10 threads
for FILE_ID in {001..072}
do
 for SAMPLE_ID in {001..020}
 do
 $TOPHAT_BINARY -G $GENE_REFERENCE -p $P -o /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID} $BOWTIE_INDEX /home/junya/bioinfo/NGS/original/Nishikawa.cell/rename_and_link/Nishi_${FILE_ID}/*_${SAMPLE_ID}.fastq.gz &
 mv /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID}/accepted_hits.bam /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID}.bam
 done
done

스크립트를 어떻게 편집하나요?

for SAMPLE_ID in {001..020}

그러면 이 명령은 빈 파일을 출력하지 않고 특정 하위 디렉터리의 특정 수의 파일에 대해서만 작동합니까?

일부 하위 디렉터리에는 2, 3, 10, 16 등의 파일 수가 포함되어 있으므로 20개만 수행했습니다. 따라서 하위 디렉터리에 샘플 파일이 2개 있으면 출력에는 18개의 빈 파일이 포함됩니다....모든 빈 파일을 제거하는 명령을 추가했습니다. 마지막으로 작동했지만 여러 하위 디렉터리에 포함된 파일만 지정하는 다른 방법이 있습니까?

## secure and fast version ###
find /home/alex/toxo/alignments/Nishi_${FILE_ID} -type f -empty -print0 | xargs -0 -I {} /bin/rm "{}"

답변1

Mel의 답변으로 문제가 해결된 것 같습니다. 여기에 또 다른 변형이 있습니다. 넓은 범위의 SAMPLE_ID를 반복하는 대신(예상한 20개보다 많으면 어떻게 될까요?) bash의 파일 이름 확장을 사용하여 실제로 존재하는 모든 샘플_* 파일만 반복하도록 루프를 변경했습니다. 홈/알렉스/toxo/alignments/Nishi_${FILE_ID}. 내가 사용하는 SAMPLE_ID의 원래 값을 되찾기 위해매개변수 확장SAMPLE_ID 파일 이름에서 마지막 세 문자를 검색합니다. Sample_* 파일이 999개가 넘으면 문제가 발생할 수 있습니다.

또한 (env를 통해) bash를 명시적으로 호출하도록 she-bang 헤더 라인을 변경했습니다. 호출이 /bin/sh인 경우 bash는 Bourne Shell을 에뮬레이션하려고 시도하고 Bourne Again SHell의 기능(예: 멋진 매개변수)을 잃게 되기 때문입니다. 확장!)

추가 보너스로 SAMPLE_FILE을 이런 방식으로 사용하면 명령이 더 짧아지고 읽기 쉬워집니다!

#!/usr/bin/env bash
TOPHAT_BINARY=/home/alex/tools/tophat-2.1.0.Linux_x86_64/tophat2
GENE_REFERENCE=/home/alex/toxo/ref/genes/ToxoDB-27_TgondiiME49.gff
BOWTIE_INDEX=/home/alex/toxo/ref/bwt/ToxoDB-27_TgondiiME49_Genome
P=10 #use 10 threads
for FILE_ID in {001..003}
do
  for SAMPLE_FILE in /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_*
  do
    SAMPLE_ID=${SAMPLE_FILE: -3}
    $TOPHAT_BINARY -G $GENE_REFERENCE -p $P -o $SAMPLE_FILE $BOWTIE_INDEX /home/junya/bioinfo/NGS/original/Nishikawa.cell/rename_and_link/Nishi_${FILE_ID}/*_${SAMPLE_ID}.fastq.gz
    mv ${SAMPLE_FILE}/accepted_hits.bam ${SAMPLE_FILE}/sample_${SAMPLE_ID}.bam
    echo
  done
done

답변2

두 번째 do줄 뒤에 새 줄을 삽입하고 다음을 입력하십시오.

if [ -a /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID} ] ; then

다시 done첫 번째 행 앞에 새 행을 삽입하고 다음을 입력하세요.

fi

파일을 처리하기 전에 파일이 존재하는지 확인합니다. 존재하지 않는 경우 SAMPLE_ID 값을 건너뜁니다.

관련 정보