다음 파일 내용이 포함된 폴더가 있습니다.
ls bams-lab/*.name-sorted.fixmate.sorted.dedup.sam
bams-lab/OZBenth2_.fastp.fq.gz.name-sorted.fixmate.sorted.dedup.sam
...
bams-lab/OZBenth7_.fastp.fq.gz.name-sorted.fixmate.sorted.dedup.sam
다음 bash 스크립트를 사용하여 파일 목록을 만들려고 합니다.
#!/bin/bash
# usage: sh merge_sam_pbs.sh /path/to/*.name-sorted.fixmate.sorted.dedup.sam
output=$(dirname $1)
samlist=$(for sam in $1; do echo "I=$sam "; done)
cat << EOF |cat #qsub
#!/bin/bash -l
#PBS -N merge
#PBS -l walltime=150:00:00
#PBS -j oe
#PBS -l mem=70G
#PBS -l ncpus=2
#PBS -M [email protected]
cd \$PBS_O_WORKDIR
conda activate picard
echo $samlist
picard -Xmx10g MergeSamFiles \
$samlist \
O=${output}/merged.sorted.dedup.bam
EOF
하지만 파일은 하나만 선택됩니다.
> sh merge_sam_pbs.sh bams-lab/*.name-sorted.fixmate.sorted.dedup.sam
#!/bin/bash -l
#PBS -N merge
#PBS -l walltime=150:00:00
#PBS -j oe
#PBS -l mem=70G
#PBS -l ncpus=2
#PBS -M [email protected]
cd $PBS_O_WORKDIR
conda activate picard
echo I=bams-lab/OZBenth2_.fastp.fq.gz.name-sorted.fixmate.sorted.dedup.sam
picard -Xmx10g MergeSamFiles I=bams-lab/OZBenth2_.fastp.fq.gz.name-sorted.fixmate.sorted.dedup.sam O=bams-lab/merged.sorted.dedup.bam
내가 놓친 게 무엇입니까?
답변1
왜냐하면 하나의 파일만 선택하기 때문입니다.$1
그냥 파일.
*
스크립트를 호출할 때 해석되므로 호출
sh merge_sam_pbs.sh bams-lab/*.name-sorted.fixmate.sorted.dedup.sam
다음과 같이 발행
sh merge_sam_pbs.sh "bams-lab/1.name-sorted.fixmate.sorted.dedup.sam" "bams-lab/2.name-sorted.fixmate.sorted.dedup.sam" "bams-lab/3.name-sorted.fixmate.sorted.dedup.sam"
그때 $1
는 입니다 "bams-lab/1.name-sorted.fixmate.sorted.dedup.sam"
.
"$@"
루프 에서 사용하고 싶습니다 for
.
samlist=$(for sam in "$@"; do echo "I=$sam "; done)
또는 for 루프를 다음으로 바꾸는 것이 더 좋습니다 printf
.
samlist=$(printf 'I=%s\n' "$@")
또는 사용 사례에 더 적합하게 줄 바꿈 대신 따옴표와 공백을 추가하십시오.
samlist=$(printf 'I="%s" ' "$@")
답변2
스크립트를 bash 쉘 스크립트로 선언했으므로 이를 사용하려는 것으로 가정합니다. (그러나 로 실행하지 마십시오 sh script
. bash script
대신 을 사용하십시오. 다른 쉘일 수 있습니다.)
samlist
문자열을 파일 요소 배열로 바꿀 수 있습니다
#!/bin/bash # usage: sh merge_sam_pbs.sh /path/to/*.name-sorted.fixmate.sorted.dedup.sam output=$(dirname $1) samlist=$(for sam in $1; do echo "I=$sam "; done)
~이 되다
#!/bin/bash
# usage: bash merge_sam_pbs.sh /path/to/*.name-sorted.fixmate.sorted.dedup.sam
# Create output directory based on first filename passed to the script
output="${1%/*}"
# For all the filenames passed to the script, prefix with 'I=', and add to array
samlist=()
for sam in "$@"
do
samlist+=("I=$sam")
done
이제 생성한 배열을 사용할 수 있습니다. 그래서 이것보다는
picard -Xmx10g MergeSamFiles \ $samlist \ O=${output}/merged.sorted.dedup.bam
당신은 이것을 사용할 수 있습니다
picard -Xmx10g MergeSamFiles "${samlist[@]}" O="$output/merged.sorted.dedup.bam"
변수를 사용할 때 모든 변수를 인용합니다. 이렇게 하면 쉘이 공백으로 구분된 개별 항목을 처리하려고 시도하는 것을 방지할 수 있습니다. 또한 "{samlist[@]}"
요소가 포함되어 있지 않으면 사라집니다. 보세요쉘 스크립트가 공백이나 기타 특수 문자로 인해 멈추는 이유는 무엇입니까?자세한 내용은.