如何在一个for循环中获取两个文件

时间:2017-03-02 09:48:18

标签: linux bash

目前正在编写一个脚本,该脚本应生成一些可以提交到集群的PBS脚本。我的正常脚本运行良好,但现在我面临着为一个程序提供两个输入文件的问题。例如,我的一个脚本如下所示:

#!/bin/bash

echo -e "#!/bin/bash\n
#SBATCH --job-name=whatever
#SBATCH --export=NONE
#SBATCH --nodes=1
#SBATCH --cpus-per-task=8
#SBATCH --mem=80G
#SBATCH --partition=blabla
#SBATCH --blabla" >> $1

echo -e "touch log_file_$1\n" >> $1

x=$( cd $( dirname ${BASH_SOURCE[0]} ) && pwd ) 

for file in /foo/bar/foo/bar/*; do
rl=$(readlink -f $file)
kw=${rl##*/} 
id=${kw%%.*} 
gz_weg=${kw%.*} 

if [ ! -d "$id" ]; then
    mkdir "$id"
fi

echo "echo $kw >> log_file_$1" >> $1
printf "foo-bar --mode barbar -e 0.001 --index /barz/barz/barz.index --inFile $rl --output $x/$id/$gz_weg.rma 2>> $x/log_file_$1 \n" >> $1
echo "echo -e '"\\n"' >> log_file_$1" >> $1
echo -e "\n" >> $1
done

我猜不是美女,但它对我有用。但现在如上所述我面临着有两个输入文件的问题。它们都在同一个文件夹中,我尝试过类似的东西:

for file in /ifs/data/nfs_share/sukmb241/raw_data/samples/iceman_old/iceman.UDG.*/*.fastq.gz; do

bs=$(basename $file)

if  [[ "$bs" == *R1* ]]; then
    r1=$(readlink -f $file)
    k1=${r1##*/}
    id1=${k1%%.*}
    gz_weg1=${k1%.*}
fi


if  [[ "$bs" == *R2* ]]; then
    r2=$(readlink -f $file)
    k2=${r2##*/}
    id2=${k2%%.*}
    gz_weg1=${k2%.*}
fi


if [ ! -d "$id1" ]; then
    mkdir "$id1"
fi

echo "echo $kw >> log_file_$1" >> $1
printf "blablabla -in1 $r1 -in2 $r2 -f foo -r bar -l 25 -qt -q 20 -o $x/$id1/whatever -verbose 2>> $x/log_file_$1 \n" >> $1
echo "echo -e '"\\n"' >> log_file_$1" >> $1
echo -e "\n" >> $1
done
fi

因为文件的文件名仅在R1或R2中有所不同。但是我意识到这将无法正常工作,因为它只会给我一个文件。那么如何解决-in1指向包含R1的文件和包含R2

的-in2的问题

提前致谢:)

1 个答案:

答案 0 :(得分:1)

如果您事先在变量中保存参数,那么您可以将参数替换为文件列表并一次使用两个:

out_file=$1
set -- /ifs/data/nfs_share/sukmb241/raw_data/samples/iceman_old/iceman.UDG.*/*.fastq.gz

while [[ -z $1 ]]
do
    # Get the next two filenames
    file1=$1
    file2=$2
    # discard them from arguments
    shift 2

    # Then the rest of the script 
    bs1=...
    # Use $out_file instead of $1
done

这可能存在参数空间不足的风险,因此您可以通过修剪路径来节省一点:

out_file=$1
dirpath=/ifs/data/nfs_share/sukmb241/raw_data/samples/iceman_old/
cd "$dirpath"
set -- iceman.UDG.*/*.fastq.gz
cd "$OLDPWD"
while [[ -z $1 ]]
do
    # Get the next two filenames
    file1="$dirpath/$1"
    file2="$dirpath/$2"
    # discard them from arguments
    shift 2
    ...

如果所有R1个文件都有相应的R2文件,那么您不需要一次取两个文件 - 只需遍历所有R1个文件,然后取出相应的R2文件:

for file in /ifs/data/nfs_share/sukmb241/raw_data/samples/iceman_old/iceman.UDG.*/*R1*.fastq.gz; do
    r1=$(readlink -f $file)
    k1=${r1##*/}
    id1=${k1%%.*}
    gz_weg1=${k1%.*}


    # Change R1 to R2 in filename
    file=${file//R1/R2}
    r2=$(readlink -f $file)
    k2=${r2##*/}
    id2=${k2%%.*}
    gz_weg2=${k2%.*}

    if [ ! -d "$id1" ]; then
        mkdir "$id1"
    fi

    echo "echo $kw >> log_file_$1" >> $1
    printf "blablabla -in1 $r1 -in2 $r2 -f foo -r bar -l 25 -qt -q 20 -o $x/$id1/whatever -verbose 2>> $x/log_file_$1 \n" >> $1
    echo "echo -e '"\\n"' >> log_file_$1" >> $1
    echo -e "\n" >> $1
done

file=${file//R1/R2}R1替换文件名中的R2,从而提供其他文件名。