авк: команд. строка: 1: фатальный: попытка деления на ноль

Я студент биоинформатики и новичок в bash и программировании. Я хочу рассчитать покрытие генома. #это мой сценарий, я переключаю реальный параметр на xx, но я уверен, что xxs не проблематичны, другие студенты уже выполняют этот скрипт без ошибок.

filename=$1
reference=/xx
filebase=$(basename $filename .bam)

samtools view ${filename} -F 4 -q 30 -b > ${filebase}.f.bam

genomeCoverageBed -ibam -g ${filebase}.f.bam  ${reference} > /mnt/ABC/projects/abc/def/${filebase}.cov

coverage=$(grep genome /mnt/ABC/projects/abc/def/${filebase}.cov | awk '{NUM+=$2*$3; DEN+=$3} END {print NUM/DEN}')

echo -e "${filename},${coverage}" >> coverages.txt

когда я выполняю этот скрипт с помощью sh ./coverage.sh /mnt/XYZ/share/sdf_rawdata/hsa/mergedbams/ghj_merged_200203.hs37d5.cons.90perc.bam

это не работает и дает мне awk: cmd. строка: 1: фатальный: попытка деления на ноль и нераспознанный параметр: /mnt/XYZ/share/sdf_rawdata/hsa/mergedbams/ghj_merged_200203.hs37d5.cons.90perc.bam ошибка, а в файле Covers.txt есть только эта строка - e /mnt/NEOGENE2/share/compevo_rawdata/hsa/mergedbams/Ash128_all.merged.hs37d5.fa.cons.90perc.bam, больше ничего. Спасибо за помощь


person azlilili    schedule 16.11.2020    source источник
comment
Это означает, что DEN равно нулю. Вы не показали содержимое ошибочной строки в $filebase.cov, поэтому мы не можем знать 3-е поле и, следовательно, не знаем, как было рассчитано DEN   -  person user1934428    schedule 16.11.2020
comment
Кроме того, ваш сценарий завершится ошибкой, если пользователь передаст имя файла с пробелами или другими метасимволами оболочки. См. Когда заключать в кавычки переменную оболочки (TLDR: в принципе всегда).   -  person tripleee    schedule 16.11.2020


Ответы (1)


Вам нужно поставить условие, чтобы проверить, является ли переменная DEN НЕ NULL, а затем выполнить деление только в блоке END кода awk (пытаясь исправить попытку OP здесь).

coverage=$(grep genome /mnt/ABC/projects/abc/def/${filebase}.cov | awk '{NUM+=$2*$3; DEN+=$3} END {if(DEN){print NUM/DEN}}')

Вам не нужно использовать команду grep вместе с awk, мы могли бы искать строку в самой awk, может быть что-то вроде:

coverage=$(awk '/genome/{NUM+=$2*$3; DEN+=$3} END {if(DEN){print NUM/DEN}}' "/mnt/ABC/projects/abc/def/${filebase}.cov")



Почему возникает ошибка: Потому что иногда ваша переменная DEN имеет нулевые значения. Давайте рассмотрим пример здесь короче (просто несколько примеров, чтобы понять ошибку здесь):

Когда переменная a равна NULL, мы также получаем ту же ошибку.

awk 'BEGIN{a="";b=1;print b/a}'
awk: cmd. line:1: fatal: division by zero attempted

Когда переменная a равна нулю, мы также получаем ту же ошибку:

awk 'BEGIN{a=0;b=1;print b/a}'
awk: cmd. line:1: fatal: division by zero attempted
person RavinderSingh13    schedule 16.11.2020
comment
Заметьте также, что все, что выглядит как grep 'x' | awk '{ y }', может быть с пользой преобразовано в awk '/x/ { y }'; см. также бесполезное использование grep. - person tripleee; 16.11.2020
comment
@tripleee, спасибо, как я уже упоминал, я исправлял попытку OP, позвольте мне написать заметку и для этой. - person RavinderSingh13; 16.11.2020
comment
Программы не должны молча выходить из строя при неправильном вводе. Ошибка деления на ноль очевидна. - person stark; 16.11.2020