Я пытаюсь написать условие if-else в сценарии оболочки/bash, которое будет использоваться для многих разных файлов, поэтому оно не будет соответствовать определенной структуре.
У меня есть три разных файла и до трех разных переменных, выбранных из каждого из этих файлов, которые входят в оператор 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
и пустыми переменными, что почти невозможно сказать. Попробуйте следовать правилам создания минимально воспроизводимого примера -- самого короткого кода кто-то другой может побежать, чтобы увидеть проблему самостоятельно, с четким разделением фактических и предполагаемых результатов — для вопросов, связанных с кодом. - person Charles Duffy   schedule 12.05.2018sed
вызовов.{ read anc1 _; read anc2 _; read anc3 _; } <file1
считывает первый столбец первых трех строк в три отдельные переменные оболочки за один проход без участия подоболочек или внешних команд. - person Charles Duffy   schedule 12.05.2018sed
здесь. Например,{ read ANC1 _; read ANC2 _; read ANC3 _; } < file1
. - person chepner   schedule 12.05.2018==
в качестве тестового оператора является нестандартным расширением (стандартный оператор сравнения строк —=
), и использование-a
или-o
для объединения нескольких тестов помечено как устаревшее (см. маркеры[OB XSI]
в pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html). И имена, написанные заглавными буквами, используются переменными, значимыми для оболочки, тогда как имена, содержащие хотя бы один символ нижнего регистра, гарантированно не повлияют на работу оболочки; см. pubs.opengroup.org/onlinepubs/9699919799/basedefs/, четвертый абзац. - person Charles Duffy   schedule 12.05.2018if
не работает так, как вы ожидаете, а вторая строка с этимif
и спрашивает, почемуif
разветвляется в одну сторону, а не в другую... это было бы намного легче следовать (и любой мог бы запустить его самостоятельно, даже в онлайн-интерпретаторе, без необходимости создаватьfile1
иfile2
и так далее). Кроме того, размещение присваиваний в вопросе с явными литералами исключает такие неожиданности, как поля файла, которые выглядят пустыми, но содержат непечатаемые символы. - person Charles Duffy   schedule 12.05.2018