我创建了一个关联数组,如下所示。为了给出一些细节,键引用了特定的文件,因为我将在更大的脚本中使用这个数组(其中包含文件的目录将是getopts参数)。
declare -A BAMREADS
echo "BAMREADS array is initialized"
BAMREADS[../data/file1.bam]=33285268
BAMREADS[../data/file2.bam]=28777698
BAMREADS[../data/file3.bam]=22388955
echo ${BAMREADS[@]} # Output: 22388955 33285268 28777698
echo ${!BAMREADS[@]} # Output: ../data/file1.bam ../data/file2.bam ../data/file3.bam到目前为止,这个数组的行为似乎与我预期的一样。现在,我想在这个数组的基础上构建另一个关联数组。具体而言:我的第二个数组将具有与第一个数组相同的键,但我希望将值除以一个名为$MIN的变量。
我不知道以下哪一种策略是最好的,我似乎无法让这两种策略发挥作用。
Strategy 1:复制数组并修改数组?
MIN=33285268
declare -A BRAMFRACS
echo "BAMFRACS array is initialized"
BAMFRACS=("${BAMREADS[@]}")
echo ${BAMFRACS[@]} # Output: 22388955 33285268 28777698
echo ${!BAMFRACS[@]} # Output: 0 1 2这不是我想要的钥匙。即使它有效,我也需要对所有的值执行我提到的操作。
Stragegy 2:在遍历第一个数组时构建第二个数组。
MIN=33285268
declare -A BRAMFRACS
echo "BAMFRACS array is initialized"
for i in $(ls $BAMFILES/*bam)
do
echo $i
echo ${BAMREADS[$i]}
BAMFRACS[$i] = ${BAMREADS[$i]}
done
echo ${BAMFRACS[@]}
echo ${!BAMFRACS[@]}
#When I run this, I get the following error which I am unsure how to solve:
../data/file1.bam
33285268
script.bash: line 108: BAMFRACS[../data/file1.bam]: No such file or directory
../data/file2.bam
28777698
script.bash: line 108: BAMFRACS[../data/file2.bam]: No such file or directory
../data/file3.bam
22388955
script.bash: line 108: BAMFRACS[../data/file3.bam]: No such file or directory谢谢
发布于 2018-08-24 12:02:45
从旧数组构建新数组:
MIN=33285268
declare -A BRAMFRACS
for key in "${!BAMREADS[@]}"; do
BRAMFRACS[$key]=$(( ${BAMREADS[$key]} / MIN ))
done对您的代码的评论:
=周围有空格。这就是你所看到的错误的来源。variable = value被解释为“使用操作数=和value执行的命令variable”。ls。相反,只需执行for pathname in "$BAMFILES"/*bam; do。printf而不是echo输出变量数据。相关信息:
发布于 2018-08-24 14:19:48
以回答有关复制关联数组的更一般问题。
当bash维护者在4.0中引入他们自己的关联数组时,他们做出了复制ksh93 API而不是zsh API的不幸决定。
ksh93/bash确实支持将关联数组设置为一个整体,但它使用的是:
hash=([k1]=v1 [k2]=v2)语法。对于zsh,它是
hash=(k1 v1 k2 v2)(为了兼容性,稍后还添加了对([k]=v...) ksh93语法的支持)。
但这意味着,使用ksh93和bash,从任意的键和值列表创建散列是非常困难的。
使用zsh语法,只需将列表作为交替键和值传递。例如,要复制两个关联数组:
h2=("${(@kv)h1}")或来自有两列的CSV:
IFS=或来自键和值数组:h=("${(@)keys:^values}")使用ksh93/bash语法,虽然有"${!h[@]}"和"${h[@]}"扩展到键和值的列表(比如zsh中的"${(@k)h}"和"${(@v)h}" ),但是在h=(...)所期望的[key]=value语法( "${(@kv)h}"在d21中)中,没有操作符可以同时展开键和值。但是,在这些shell中复制关联数组(除了在循环中复制元素之外)的一个技巧是使用typeset -p的输出。例如,等效于zsh's h2=("${(@kv)h1}")将h1复制到h2中,可以在ksh93或bash中使用:h1_definition=$(typeset -p h1) &&
eval "typeset -A h2=${h1_definition#*=}"使用bash,您可以将其缩短为:h1_definition=$(typeset -p h1) &&
typeset -A h2="${h1_definition#*=}"(与ksh93类似,typeset -A h=value是bash中typeset -A h=([0]=value)的缩写,如果value以(开头,以)结尾,则内容被解释为复合关联赋值,就好像传递给eval (即使引用(或某些扩展的结果))。最后,使用循环也同样容易:for k in "${!h1[@]}"; do h2[$k]=${h1[$k]}; done\n,'; h=($(或来自键和值数组:
A10
使用D11/D12语法,虽然有D13和D14扩展到键和值的列表(比如D17中的D15和D16 ),但是在D19所期望的D18语法( D20在d21中)中,没有操作符可以同时展开键和值。
但是,在这些shell中复制关联数组(除了在循环中复制元素之外)的一个技巧是使用D22的输出。
例如,等效于D23's D24将D25复制到D26中,可以在D27或D28中使用:
A29
使用D30,您可以将其缩短为:
A31
(与ksh93类似,D32是D34中D33的缩写,如果D35以D36开头,以D37结尾,则内容被解释为复合关联赋值,就好像传递给D38 (即使引用D39或某些扩展的结果))。
最后,使用循环也同样容易:
A40
发布于 2020-05-06 23:26:24
这应该可以做到(还可以添加额外的键值):
declare -A origDict=( [keya]=value_a [keyb]=value_b [keyc]=value_c )
declare -a newDict=( echo ${origDict[*]} [keynew]=new_value )https://unix.stackexchange.com/questions/464626
复制相似问题