目前正在编写一个脚本,该脚本应生成一些可以提交到集群的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的问题提前致谢:)
答案 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
,从而提供其他文件名。