在bash数组中获取shell命令的输出

时间:2015-03-30 21:08:13

标签: arrays bash shell ubuntu-14.04

我有一个uniq -c输出,输出大约7-10行,每个模式的计数对每个独特的行模式重复。我想将uniq -c file.txt的输出存储到bash数组中。现在我所能做的就是将输出存储到变量中并打印出来。但是,bash目前认为整个输出只是一个大字符串。

bash如何识别分隔符?如何将UNIX shell命令输出存储为Bash数组?

这是我目前的代码:

proVar=`awk '{printf ("%s\t\n"), $1}' file.txt | grep -P 'pattern' | uniq -c`
echo $proVar

我得到的当前输出:

587 chr1 578 chr2 359 chr3 412 chr4 495 chr5 362 chr6 287 chr7 408 chr8 285 chr9 287 chr10 305 chr11 446 chr12 247 chr13 307 chr14 308 chr15 365 chr16 342 chr17 245 chr18 252 chr19 210 chr20 193 chr21 173 chr22 145 chrX 58 chrY

这就是我想要的:

proVar[1] = 2051
proVar[2] = 1243
proVar[3] = 1068
...
proVar[22] = 814 
proVar[X] = 72
proVar[Y] = 13 

从长远来看,我希望根据每个指数的计数制作一个条形图,其中每50个计数等于一个" ="标志。希望看起来像下面的

chr1 ===========
chr2 ===========
chr3 =======
chr4 =========
...
chrX ==
chrY =

任何帮助,伙计们?

2 个答案:

答案 0 :(得分:3)

要构建关联数组,请尝试以下方法:

declare -A proVar
while read -r val key; do
  proVar[${key#chr}]=$val
done < <(awk '{printf ("%s\t\n"), $1}' file.txt | grep -P 'pattern' | uniq -c)

注意:这假设您的命令输出由多个行组成,每行包含一个键值对;您问题中显示的单行输出来自将$proVar传递给没有双引号的echo。

  • 使用while循环从流程替换中读取每个输出行(<(...))。
  • 每个assoc的。数组条目是通过从每个输入行的第一个空格分隔的标记中删除前缀chr而形成的,而是该行的其余部分(在分隔空间之后)。 / LI>

然后创建条形图,使用:

while IFS= read -r key; do
  echo "chr${key} $(printf '=%.s' $(seq $(( ${proVar[$key]} / 50 ))))"
done < <(printf '%s\n' "${!proVar[@]}" | sort -n)

注意:使用sort -n对键进行排序会在数字键之前输入XY 之类的非数字键。

  • $(( ${proVar[$key]} / 50 ))计算=个字符的数量。在算术扩展中使用整数除法显示。
  • $(seq ...)的目的是简单地创建与=字符一样多的标记(参数)。应该显示(创建的代币是数字,但它们的内容并不重要)。
  • printf '=%.s' ...是一种有效打印=个字符的技巧。因为格式字符串后面有参数。
  • printf '%s\n' "${!proVar[@]}" | sort -n对assoc的键进行排序。数组中的数组,其输出通过进程替换馈送到while循环,因此按排序顺序迭代键。

答案 1 :(得分:0)

您可以使用括号在作业中创建数组:

proVar=(`awk '{printf ("%s\t\n"), $1}' file.txt | grep -P 'pattern' | uniq -c`)

没有内置方法可以直接从输入创建关联数组。为此,你需要一个额外的循环。