Usando uma matriz bash em uma variável awk e também entre aspas: problema de sintaxe conflitante

3

Eu tenho um script cujo objetivo é:

  • Para obter uma lista de arquivos, obtenha um número específico para cada arquivo (isto é, dados de sequenciamento, para serem específicos) e armazene-os em array1
  • Usando array1, encontre o menor número é array1
  • Com base no menor número em array1, divida todos por todos os números em array1 para criar array2.

Meu script é o seguinte:

#!/usr/bin/bash



USAGE() { echo "Usage: bash $0 [-b <in-bam-files-dir>] [-o <out-dir>] [-c <chromlen>]" 1>&2; exit 1; }

if (($# == 0))
then
    USAGE
fi



while getopts ":b:o:c:h" opt
do
    case $opt in
        b ) BAMFILES=$OPTARG
        ;;
        o ) OUTDIR=$OPTARG
        ;;
        c ) CHROMLEN=$OPTARG
        ;;
        h ) USAGE
        ;;
        \? ) echo "Invalid option: -$OPTARG exiting" >&2
        exit
        ;;
        : ) echo "Option -$OPTARG requires an argument" >&2
        exit
        ;;
    esac
done



if [ ! -d ${OUTDIR} ]
then
    mkdir ${OUTDIR}
fi

if [ ! -d ${OUTDIR}/temp ]
then
    mkdir ${OUTDIR}/temp
fi

if [ -d ${BAMFILES} ]
then
    echo -e "\nProcessing BAM files from following directory: ${BAMFILES} \n "
fi



module purge
module load samtools
module load bedtools
module load ucsctools
echo -e "Modules are loaded\n"



FIRSTBAM=$(ls $BAMFILES/*bam | head -1)
MIN=$(samtools view -c -F 260 ${FIRSTBAM} )
echo -e "Minimum number of reads is currently set to $MIN from $FIRSTBAM (first bam in directory)\n"



declare -A BAMREADS
echo "BAMREADS array is initialized"

for i in $(ls $BAMFILES/*bam)
do
    echo "Counting reads in $i "
    BAMREADS[$i]=$(samtools view -c -F 260 $i)
done



for i in ${BAMREADS[@]}
do
    if [[ $i -lt $MIN ]]
    then
        MIN=$i
    fi
done

echo -e "Minimum number of reads that will be used for scaling is $MIN \n"



declare -A BAMFRACS
echo -e "BAMFRACS array is initialized"

for i in ${!BAMREADS[@]}
do
    BAMFRACS[$i]=$(awk -v var1=${MIN} -v var2=${BAMREADS[$i]} 'BEGIN { x= var1 / var2; printf "%.8f", x }')
done



for i in $(ls $BAMFILES/*bam)
do

    SAMPLE='basename $i'
    SAMPLE=${SAMPLE%.bam}
    echo $SAMPLE

    if [[ ${BAMREADS[$i]} -eq $MIN ]]
    then

        echo "Sample $i does not need scaling"

        command="cp $i ${OUTDIR}/temp/${SAMPLE}.scaled.bam;
        genomeCoverageBed -bg -split -ibam ${OUTDIR}/temp/${SAMPLE}.scaled.bam > ${OUTDIR}/temp/${SAMPLE}.bedgraph;
        sed -e 's/^/chr/g;s/MT/M/g' ${OUTDIR}/temp/${SAMPLE}.bedgraph > ${OUTDIR}/temp/${SAMPLE}.modified.bedgraph;
        sort -k1,1 -k2,2n ${OUTDIR}/temp/${SAMPLE}.modified.bedgraph > ${OUTDIR}/temp/${SAMPLE}.sorted.bedgraph;
        bedGraphToBigWig ${OUTDIR}/temp/${SAMPLE}.sorted.bedgraph $CHROMLEN ${OUTDIR}/${SAMPLE}.bw"
        #rm ${OUTDIR}/temp/${SAMPLE}.*

    else

        command="samtools view -s ${BAMFRACS[$i]} -b $i > ${OUTDIR}/temp/${SAMPLE}.scaled.bam;
        genomeCoverageBed -bg -split -ibam ${OUTDIR}/temp/${SAMPLE}.scaled.bam > ${OUTDIR}/temp/${SAMPLE}.bedgraph;
        sed -e 's/^/chr/g;s/MT/M/g' ${OUTDIR}/temp/${SAMPLE}.bedgraph > ${OUTDIR}/temp/${SAMPLE}.modified.bedgraph;
        sort -k1,1 -k2,2n ${OUTDIR}/temp/${SAMPLE}.modified.bedgraph > ${OUTDIR}/temp/${SAMPLE}.sorted.bedgraph;
        bedGraphToBigWig ${OUTDIR}/temp/${SAMPLE}.sorted.bedgraph $CHROMLEN ${OUTDIR}/${SAMPLE}.bw"
        #rm ${OUTDIR}/temp/${SAMPLE}.*

    fi

    echo $command | qsub -V -cwd -o $OUTDIR -e $OUTDIR -l tmem=10G -l h_vmem=10G -l h_rt=3600 -N bigwig_${SAMPLE}

 done

 echo "Task completed: conversion jobs submitted to cluster"

Eu tenho 2 perguntas:

  • Pelo que entendi, bash não é muito bom em fazer matemática aritmética: ou seja, fazer qualquer tipo de operação (adição, divisão, etc.) envolvendo números flutuantes. No entanto, dado o fato de que var1 e var2 são sempre inteiros no meu script (veja $ MIN e todos os valores da matriz1), concordamos que isso não é um problema? Ou seja minha operação resulta em números flutuantes, mas usa números inteiros, então não é um problema, certo?

  • Não está muito claro no StackExchange porque não há realce de sintaxe aqui, mas notei que a parte var2 = $ {BAMREADS [$ i]} do meu script não está correta. Eu uso nano e no meu terminal, em vez de ter todos os $ {BAMREADS [$ i]} em vermelho, como as outras variáveis (como $ {MIN}), somente a parte $ {BAMREADS [$ i do script é aparecem em vermelho, isto é, o final]} não é vermelho. O script parece estar se comportando como eu esperava e tudo parece estar funcionando. Então, eu não entendo muito bem por que não está tudo vermelho.

É assim que meu script se parece no nano (observe como o}} em $ {BAMREADS [$ i]} no comando awk E mais tarde no segundo comando $ não está em vermelho como deveria ser):

Noentanto,sevocêcolaressecódigono link , não há nenhum problema em destacar nessa parte do roteiro. Então, como é que o nano e o shellcheck não me dizem a mesma coisa? Eu usei este script e parece funcionar para mim, mas estou preocupado com esta questão de destaque ..

Obrigado

    
por m93 17.09.2018 / 11:29

1 resposta

3

O destaque da sintaxe é um problema

Cada editor tem suas próprias desvantagens / vantagens dessa maneira.

Veja minha pergunta sobre SoftwareRecs e suas respectivas respostas, mais importante isso para CLI e GUI e isso para GUI .

Em especial, Código do Visual Studio , tem IMHO a melhor realce de Sintaxe dos editores de GUI.

Nos editores CLI, consulte a resposta de gVim , que faz o mesmo trabalho de realce de sintaxe para o CLI.

Note que como eu era um usuário nano pesado, posso dizer que nano não consegue distinguir as variáveis dentro de aspas.

Aspas duplas ausentes são um problema maior

O que deve incomodar mais é que você não usou - suponho que você não está acostumado - mau hábito - as aspas duplas. Por favor, consulte o StackOverflow para mais informações ou simplesmente use o Google. Ou veja abaixo.

Aspas duplas para impedir globbing e divisão de palavras

Para escritores de script de shell, o nano editor dificilmente pode ser usado, porque não reconhecerá variáveis de dentro de uma string (aspas), o que é muito ruim para cada script de shell. Aspas duplas são completamente essenciais em scripts de shell. Eles evitam o chamado globbing e a divisão de palavras, leia o artigo da ShellCheck Wiki SC2086 para obter mais informações sobre este tópico.

Sempre envie seus scripts para ShellCheck

    
por 17.09.2018 / 13:26