【发布时间】:2018-05-12 19:07:30
【问题描述】:
我正在尝试在 shell/bash 脚本中编写一个 if-else 条件,该条件将用于许多不同的文件,因此它不适合特定的结构。
我有三个不同的文件,并且从这些文件中的每个文件中选择最多三个不同的变量进入 if-else 语句。在我的脚本中,我在开头写了这个(可能可以用更好的方式写)如下:
ANC1=$(sed -n 1p file1 | cut -f 1 -d' ' )
ANC2=$(sed -n 2p file1 | cut -f 1 -d' ' )
ANC3=$(sed -n 3p file1 | cut -f 1 -d' ' )
ANC11=$(sed -n 1p file2 | cut -f 1 -d' ' )
ANC21=$(sed -n 2p file2 | cut -f 1 -d' ' )
ANC31=$(sed -n 3p file2 | cut -f 1 -d' ' )
ANC15=$(sed -n 1p file3 | cut -f 1 -d' ' )
ANC25=$(sed -n 2p file3 | cut -f 1 -d' ' )
ANC35=$(sed -n 3p file3 | cut -f 1 -d' ' )
例如,从这些文件中,可能会产生以下变量:
echo ${ANC1}
FIN
echo ${ANC2}
NFE
echo ${ANC3}
echo ${ANC11}
FIN
echo ${ANC21}
NFE
echo ${ANC31}
echo ${ANC15}
FIN
echo ${ANC25}
NFE
echo ${ANC35}
SAS
从这里开始,我编写了 if-else 语句(考虑到上述三个文件中可能缺少的变量)。为了理解它,尝试执行以下操作:
第一个条件:如果所有变量都不为空; 第二个条件:如果第三个变量是唯一缺失的变量; 第三个条件:如果第三个和第二个变量都为空
if [ "${ANC3}" != "" ] || [ "${ANC31}" != "" ] || [ "${ANC35}" != "" ]; then
echo "***** three variables *****"
bcftools merge -m both \
fileref1.genotypes_${ANC1}.vcf.gz \
fileref1.genotypes_${ANC2}.vcf.gz \
fileref1.genotypes_${ANC3}.vcf.gz \
-Oz \
-o fileref1.new.genotypes_${ANC1}.${ANC2}.${ANC3}.vcf.gz
bcftools merge -m both \
fileref2.genotypes_${ANC11}.vcf.gz \
fileref2.genotypes_${ANC21}.vcf.gz \
fileref2.genotypes_${ANC31}.vcf.gz \
-Oz \
-o fileref2.new.genotypes_${ANC11}.${ANC21}.${ANC31}.vcf.gz
bcftools merge -m both \
fileref3.genotypes_${ANC15}.vcf.gz \
fileref3.genotypes_${ANC25}.vcf.gz \
fileref3.genotypes_${ANC35}.vcf.gz \
-Oz \
-o fileref1.new.genotypes_${ANC15}.${ANC25}.${ANC35}.vcf.gz
elif
[ "${ANC3}" == "" -a "${ANC2}" != "" ] || [ "${ANC31}" == "" -a "${ANC21}" != "" ] || [ "${ANC35}" == "" -a "${ANC25}" != "" ]; then
echo "***** two variables *****"
bcftools merge -m both \
fileref1.genotypes_${ANC1}.vcf.gz \
fileref1.genotypes_${ANC2}.vcf.gz \
-Oz \
-o fileref1.new.genotypes_${ANC1}.${ANC2}.vcf.gz
bcftools merge -m both \
fileref2.genotypes_${ANC11}.vcf.gz \
fileref2.genotypes_${ANC21}.vcf.gz \
-Oz \
-o fileref2.new.genotypes_${ANC11}.${ANC21}.vcf.gz
bcftools merge -m both \
fileref3.genotypes_${ANC15}.vcf.gz \
fileref3.genotypes_${ANC25}.vcf.gz \
-Oz \
-o fileref1.new.genotypes_${ANC15}.${ANC25}.vcf.gz
elif
[ "${ANC3}" == "" -a "${ANC2}" == "" ] || [ "${ANC31}" == "" -a "${ANC21}" == "" ] || [ "${ANC35}" == "" -a "${ANC25}" == "" ]; then
echo "***** one variable ***** "
cp fileref1.genotypes_${ANC1}.vcf.gz fileref1.new.genotypes_${ANC1}.${ANC2}.vcf.gz
cp fileref2.genotypes_${ANC11}.vcf.gz fileref2.new.genotypes_${ANC11}.vcf.gz
cp fileref3.genotypes_${ANC15}.vcf.gz fileref1.new.genotypes_${ANC15}.vcf.gz
fi
每次我运行这个脚本时,都应该生成 3 个文件,但有时情况并非如此。第一部分有效(对于所有变量都不为空的文件) - 但第二个和第三个条件似乎没有。我也试过[ -z "${ANC3}" ] 和[ -n "${ANC2}" ] 分别表示缺失和非缺失,但这也不起作用。还尝试了[[ ]] 与[ ] 相比,但仍然相同。
我明显遗漏了什么?
【问题讨论】:
-
变量真的是空的,还是包含空白字符?
-
我们几乎肯定有您的问题的副本,但它是如此隐藏在代码中,与
if语句和空变量无关,几乎无法分辨。对于涉及代码的问题,请尝试遵循有关构建minimal reproducible example 的规则——尽可能短的代码其他人可以运行以自行查看问题,并清楚区分实际和预期的输出。 -
顺便说一句,与一堆
sed调用相比,将前三行中的字段读取到变量中的方法有很多,很多。{ read anc1 _; read anc2 _; read anc3 _; } <file1一次将前三行的第一列读入三个单独的 shell 变量,不涉及子 shell 或外部命令。 -
这里不需要
sed。例如,{ read ANC1 _; read ANC2 _; read ANC3 _; } < file1。 -
顺便说一句,还要注意
==作为测试运算符是一个非标准扩展(标准字符串比较运算符是=),使用-a或-o组合多个测试是标记为过时(参见pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html 中的[OB XSI]标记)。并且全大写的名称由对 shell 有意义的变量使用,而具有至少一个小写字符的名称保证不会影响 shell 操作;见pubs.opengroup.org/onlinepubs/9699919799/basedefs/…,第四段。
标签: bash if-statement bioinformatics bcftools