Bash에서 파일 목록 생성이 실패했습니다.

Bash에서 파일 목록 생성이 실패했습니다.

다음 파일 내용이 포함된 폴더가 있습니다.

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[@]}"요소가 포함되어 있지 않으면 사라집니다. 보세요쉘 스크립트가 공백이나 기타 특수 문자로 인해 멈추는 이유는 무엇입니까?자세한 내용은.

관련 정보