在 bash 数组中获取 shell 命令的输出
Getting output of shell command in bash array
我有一个 uniq -c 输出,它输出大约 7-10 行,其中包含为每个唯一行模式重复的每个模式的计数。我想将 uniq -c file.txt 的输出存储到 bash 数组中。现在我所能做的就是将输出存储到一个变量中并打印出来。然而,bash 目前认为整个输出只是一个大字符串。
bash 如何识别定界符?如何将 UNIX shell 命令输出存储为 Bash 数组?
这是我当前的代码:
proVar=`awk '{printf ("%s\t\n"), }' 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 =
伙计们,有什么帮助吗?
您可以使用括号在赋值中创建数组:
proVar=(`awk '{printf ("%s\t\n"), }' file.txt | grep -P 'pattern' | uniq -c`)
没有直接从输入创建关联数组的内置方法。为此,您需要一个额外的循环。
要构建关联数组,试试这个:
declare -A proVar
while read -r val key; do
proVar[${key#chr}]=$val
done < <(awk '{printf ("%s\t\n"), }' file.txt | grep -P 'pattern' | uniq -c)
注意:这假定您的命令的输出由 多行 行组成,每行包含 一个 键值一对;您问题中显示的单行输出来自将 $proVar
传递给不带双引号的 echo。
- 使用
while
循环从进程替换 (<(...)
) 中读取每个输出行。
- 每个关联的键。数组条目是通过从每个输入行的第一个白色 space 分隔标记中剥离前缀
chr
形成的,而 value 是行的其余部分(在分隔之后space).
然后要创建条形图,请使用:
while IFS= read -r key; do
echo "chr${key} $(printf '=%.s' $(seq $(( ${proVar[$key]} / 50 ))))"
done < <(printf '%s\n' "${!proVar[@]}" | sort -n)
注意:使用sort -n
对key进行排序会将非数字key如X
和Y
放在之前 输出中的数字。
$(( ${proVar[$key]} / 50 ))
计算 =
个字符的数量。显示,在算术展开中使用 整数 除法。
$(seq ...)
的目的是简单地创建与 =
个字符一样多的 标记(参数)。应该显示(创建的标记是数字,但它们的内容无关紧要)。
printf '=%.s' ...
是一种有效打印尽可能多的 =
个字符的技巧。因为格式字符串后面有参数。
printf '%s\n' "${!proVar[@]}" | sort -n
对关联的键进行排序。数组,其输出通过进程替换提供给 while
循环,因此循环按排序顺序遍历键。
我有一个 uniq -c 输出,它输出大约 7-10 行,其中包含为每个唯一行模式重复的每个模式的计数。我想将 uniq -c file.txt 的输出存储到 bash 数组中。现在我所能做的就是将输出存储到一个变量中并打印出来。然而,bash 目前认为整个输出只是一个大字符串。
bash 如何识别定界符?如何将 UNIX shell 命令输出存储为 Bash 数组?
这是我当前的代码:
proVar=`awk '{printf ("%s\t\n"), }' 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 =
伙计们,有什么帮助吗?
您可以使用括号在赋值中创建数组:
proVar=(`awk '{printf ("%s\t\n"), }' file.txt | grep -P 'pattern' | uniq -c`)
没有直接从输入创建关联数组的内置方法。为此,您需要一个额外的循环。
要构建关联数组,试试这个:
declare -A proVar
while read -r val key; do
proVar[${key#chr}]=$val
done < <(awk '{printf ("%s\t\n"), }' file.txt | grep -P 'pattern' | uniq -c)
注意:这假定您的命令的输出由 多行 行组成,每行包含 一个 键值一对;您问题中显示的单行输出来自将 $proVar
传递给不带双引号的 echo。
- 使用
while
循环从进程替换 (<(...)
) 中读取每个输出行。 - 每个关联的键。数组条目是通过从每个输入行的第一个白色 space 分隔标记中剥离前缀
chr
形成的,而 value 是行的其余部分(在分隔之后space).
然后要创建条形图,请使用:
while IFS= read -r key; do
echo "chr${key} $(printf '=%.s' $(seq $(( ${proVar[$key]} / 50 ))))"
done < <(printf '%s\n' "${!proVar[@]}" | sort -n)
注意:使用sort -n
对key进行排序会将非数字key如X
和Y
放在之前 输出中的数字。
$(( ${proVar[$key]} / 50 ))
计算=
个字符的数量。显示,在算术展开中使用 整数 除法。$(seq ...)
的目的是简单地创建与=
个字符一样多的 标记(参数)。应该显示(创建的标记是数字,但它们的内容无关紧要)。printf '=%.s' ...
是一种有效打印尽可能多的=
个字符的技巧。因为格式字符串后面有参数。printf '%s\n' "${!proVar[@]}" | sort -n
对关联的键进行排序。数组,其输出通过进程替换提供给while
循环,因此循环按排序顺序遍历键。