AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 469516
Accepted
mf94
mf94
Asked: 2018-09-18 01:29:58 +0800 CST2018-09-18 01:29:58 +0800 CST 2018-09-18 01:29:58 +0800 CST

在 awk 中使用 bash 数组并引用变量:语法冲突问题

  • 772

我有一个脚本,其目的是:

  • 对于文件列表,获取每个文件的特定编号(具体来说,这是测序数据)并将这些存储到 array1
  • 使用array1,找到最小的数是array1
  • 根据 array1 中最小的数字,将它除以 array1 中的所有数字,得到 array2。

我的脚本如下所示:

#!/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"

我有两个问题:

  • 据我了解,bash 不太擅长算术运算:即进行涉及浮点数的任何类型的运算(加法、除法等)。但是,鉴于 var1 和 var2 在我的脚本中始终是整数(请参阅 $MIN 和所有 array1 值),我们是否同意这不是问题?即我的操作结果是浮点数,但它使用整数,所以这不是问题,对吗?

  • 在 StackExchange 中不是很清楚,因为这里没有突出显示语法,但我注意到我脚本的 var2=${BAMREADS[$i]} 部分不太正确。我在我的终端中使用 nano,而不是像其他变量(如 ${MIN})一样将所有的 ${BAMREADS[$i]} 都设为红色,而只有脚本的 ${BAMREADS[$i] 部分是以红色出现,即结尾]}不是红色。该脚本的行为似乎与我预期的一样,一切似乎都在工作。所以我不太明白为什么它不是全部都是红色的。

这就是我的脚本在 nano 中的样子(请注意 awk 命令中 ${BAMREADS[$i]} 中的 ]} 以及稍后在第二个 $command 中的 ]} 不是红色的,因为它应该是红色的):

在此处输入图像描述

但是,如果您将此代码粘贴到https://www.shellcheck.net/中,就脚本的这一部分的突出显示而言,您不会遇到任何问题。那么 nano 和 shellcheck 怎么没有告诉我同样的事情呢?我已经使用了这个脚本,它似乎对我有用,但我担心这个突出显示的问题..

谢谢

shell-script syntax
  • 1 1 个回答
  • 187 Views

1 个回答

  • Voted
  1. Best Answer
    Vlastimil Burián
    2018-09-18T03:26:58+08:002018-09-18T03:26:58+08:00

    语法高亮是一个问题

    每个编辑器在这种方式上都有自己的缺点/优点。

    请参阅我关于SoftwareRecs的问题及其各自的答案,最重要的是这对于 CLI 和 GUI以及this 对于 GUI。

    值得注意的是,Visual Studio Code恕我直言,是 GUI 编辑器中最好的语法突出显示。

    从 CLI 编辑器中,参考 的答案gVim,它为 CLI 执行相同的语法突出显示工作。

    请注意,由于我是重度nano用户,我可以告诉您nano无法区分引号内的变量。


    缺少双引号是一个更大的问题

    最让你烦恼的是你没有使用——我想你不习惯——坏习惯——双引号。请参考 StackOverflow 了解更多信息或直接使用 Google。或见下文。


    双引号以防止通配符和分词

    对于 shell 脚本编写者来说,nano编辑器几乎没有用处,因为它无法识别字符串内部(引号)中的变量,这对每个 shell 脚本编写者来说都是非常糟糕的。双引号在 shell 脚本中是必不可少的。它们防止所谓的通配符和单词拆分,请阅读ShellCheck Wiki 文章 SC2086以获取有关此主题的更多信息。


    始终将您的脚本通过管道传输到ShellCheck

    • 3

相关问题

  • 在awk中的两行之间减去相同的列

  • 打印文件行及其长度的脚本[关闭]

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 按分隔符拆分并连接字符串问题

  • MySQL Select with function IN () with bash array

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve