for 루프가 예상대로 작동하지 않습니다.

for 루프가 예상대로 작동하지 않습니다.

teefor 루프에서 사용하려고 합니다.

for ea in $(ls *bam)
  do samtools mpileup -f $ref $ea | \
  tee \
  >(java -jar $varscan2 mpileup2indel --output-vcf 1 > vcf/"$(echo $ea | sed s/.bam//)"_mpileup2indel.vcf) \
  >(java -jar $varscan2 mpileup2snp --output-vcf 1 > vcf/"$(echo $ea | sed s/.bam//)"_mpileup2snp.vcf) | \
  tail -n 5
done;

즉, 출력을 가져와 samtools mpileup두 개의 별도 명령으로 파이프합니다. tail -n 5출력이 완전히 stdout으로 인쇄되는 것을 방지하기 위해 이것을 추가했습니다 samtools mpileup(그러나 전체 출력을 input 으로 사용하고 싶습니다 java -jar varscan).

이는 처음에는 작동하는 것처럼 보이지만 명령이 완료되지 않는 것 같습니다(각 출력의 파일 크기는 명령을 실행하지 않았을 때보다 작습니다 tee).

결국 이 두 java -jar $varscan명령이 결코 도착하지 않는 입력을 기다리고 있다는 오류가 발생합니다(루프의 두 번째 반복을 시작하기 전에).

이것이 내가 원하는 것을 달성하는 가장 좋은 방법, 즉 두 개의 개별 명령에서 첫 번째 명령의 출력을 사용하는 것입니다(이상적으로는 첫 번째 명령의 출력을 전혀 기록/인쇄하지 않음)? teefor 루프와 호환되지 않나요?

미리 감사드립니다.

답변1

  1. 변수 참조
  2. ls를 구문 분석하지 마세요
  3. 선택사항이지만 권장됨: 스크립트를 단순화하고반복하지 마세요. sed를 사용하여 기본 이름을 두 번 생성하고 매번 다른 접미사를 추가합니다. 한 번 생성하는 것이 더 좋습니다. 이렇게 하면 오류 위험이 줄어들고 가독성이 향상됩니다. 성능도 약간 향상됩니다. 어떤 작업을 한 번 수행하는 것이 "더 저렴"합니다. 정확히 동일한 작업을 두 번 이상 수행하는 것보다 결과를 재사용하는 것입니다.
  4. 가독성(예: 읽기 및이해하다당신이 작성한 프로그램)은 그 중 하나입니다. 그렇지 않은 경우이것코드를 작성할 때 가장 중요한 것은... 따라서 성능이 절대적으로 중요하지 않은 한, 보다 이해하기 쉬운 방식으로 코드 작성의 우선순위를 지정하는 것이 가장 좋습니다. 이는 더 많은 줄 바꿈이나 들여쓰기를 삽입하거나 길고 복잡한 명령을 더 짧고 간단한 명령으로 나누는 것을 의미할 수 있습니다. 이는 지금 스크립트를 작성하고 디버그하는 데 도움이 되며 X개월(또는 몇 년) 후에 다시 방문해야 할 때 스크립트를 이해하는 데도 도움이 됩니다.
for ea in *.bam; do
  bn="$(basename "$ea" .bam)"
  samtools mpileup -f "$ref" "$ea" |
    tee \
      >(java -jar "$varscan2" mpileup2indel --output-vcf 1 > "vcf/${bn}_mpileup2indel.vcf") \
      >(java -jar "$varscan2" mpileup2snp --output-vcf 1 > "vcf/${bn}_mpileup2snp.vcf") |
    tail -n 5
done

다양한 들여쓰기 수준을 확인하세요. 예를 들어, tee는 samtools에서 약간 들여쓰기되고, tee의 인수는 tee에서 들여쓰기된 다음 tee와 동일한 들여쓰기 수준으로 되돌아갑니다. 이 모든 것은 어떤 매개변수가 어떤 프로그램에 속하는지, 그리고 이를 읽을 때 파이프라인(또는 루프 등)의 어디에 있는지 이해하는 데 도움이 됩니다.

그런데 파이프 문자 뒤에 줄을 계속하는 데 사용되는 백슬래시는 선택 사항입니다.

심지어:

outdir="vcf"

for ea in *.bam; do
  bn="$(basename "$ea" .bam)"
  indel="$outdir/${bn}_mpileup2indel.vcf"
  snp="$outdir/${bn}_mpileup2snp.vcf"

  samtools mpileup -f "$ref" "$ea" |
    tee \
      >(java -jar "$varscan2" mpileup2indel --output-vcf 1 > "$indel") \
      >(java -jar "$varscan2" ​mpileup2snp --output-vcf 1 > "$snp") |
 ​   tail -n 5
done

관련 정보