在 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 shell 脚本,因此我假设这就是您打算使用的脚本。 (不过,不要使用 运行它sh scriptbash script而是使用。它们可以是不同的 shell。)

您可以将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"

请注意,我在使用所有变量时都引用了它们。这会阻止 shell 尝试处理各个以空格分隔的项目。此外,如果"{samlist[@]}"不包含任何元素,它就会消失。看一眼为什么我的 shell 脚本因空格或其他特殊字符而卡住更多细节。

相关内容