
tee
다음과 같이 for 루프에서 사용하려고 합니다 .
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
(그러나 전체 출력을 의 입력으로 사용하고 싶습니다 java -jar varscan
).
이것은 처음에는 작동하는 것처럼 보이지만 명령이 완료되지 않는 것 같습니다(각 출력의 파일 크기는 명령이 없이 수행된 경우보다 작습니다 tee
).
결국 두 java -jar $varscan
명령이 결코 도착하지 않는 입력을 기다리고 있다는 오류가 발생합니다(루프의 두 번째 반복을 시작할 기회를 얻기 전에).
이것이 내가 원하는 것을 달성하는 가장 좋은 방법입니까? 즉, 두 개의 개별 명령에서 첫 번째 명령의 출력을 사용하는 것입니다(이상적으로는 첫 번째 명령의 출력을 전혀 기록/인쇄하지 않는 것)? tee
for 루프와 호환되지 않나요 ?
미리 감사드립니다.
답변1
- 변수를 인용해 보세요
- ls를 구문 분석하지 마세요
- 선택 사항이지만 권장 사항: 스크립트를 단순화하고반복하지 마세요. sed를 사용하여 기본 이름을 두 번 생성하고 매번 다른 접미사를 추가합니다. 한 번 생성하는 것이 더 좋습니다. 이렇게 하면 버그 위험이 줄어들고 가독성이 향상됩니다(그리고 성능이 약간 향상됩니다. 작업을 수행하는 것이 "저렴"합니다. 정확히 동일한 작업을 두 번 이상 수행하는 것보다 한 번만 실행하면 결과를 다시 사용할 수 있습니다.
- 가독성(즉, 읽고 쓰는 능력)이해하다당신이 작성한 프로그램)은 다음 중 하나입니다. 그렇지 않은 경우그만큼코드를 작성할 때 가장 중요한 것....따라서 성능이 절대적으로 중요하지 않은 경우에는 이해하기 쉬운 방식으로 코드 작성의 우선순위를 지정하는 것이 좋습니다. 이는 더 많은 줄 바꿈이나 들여쓰기를 삽입하거나 길고 복잡한 명령을 더 짧고 간단한 명령으로 나누는 것을 의미할 수 있습니다. 이는 지금 스크립트를 작성하고 디버깅하는 데 도움이 되며 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에서 들여쓰기되고, tail은 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