“推”到bash关联数组

时间:2017-05-10 12:07:06

标签: arrays bash associative-array

我正在尝试为具有公共ID的目录中的所有文件运行脚本。

ls -1 *.vcf

a1.sourceA.vcf
a1.sourceB.vcf
a1.sourceC.vcf
a2.sourceA.vcf
a2.sourceB.vcf
a2.sourceC.vcf
a3.sourceA.vcf
a3.sourceC.vcf

每种情况下的ID都在第一个.a1a2a3)之前,对于每个ID,我希望拥有该ID的所有来源一个关联数组,由ID键入,例如;

a1 => [a1.sourceA.vcfa1.sourceB.vcfa1.sourceC.vcf]

我的尝试如下:

for file in $(ls *.vcf | sort)
do
  id=$(echo $file | cut -d '.' -f 1)
  vcfs[$id]+=$file

done

for i in "${!vcfs[@]}"
do
  echo "key  : $i"
  echo "value: ${vcfs[$i]}"
  echo " "
done

但我无法弄清楚如何让它发挥作用。

在Perl中,我会将值推送到循环中的数组哈希:

push @{$vcfs{$id}}, $file;

给我一​​个这样的数据结构:

  'a1' => [
            'a1.sourceA.vcf',
            'a1.sourceB.vcf',
            'a1.sourceC.vcf'
          ],
  'a3' => [
            'a3.sourceA.vcf',
            'a3.sourceC.vcf'
          ],
  'a2' => [
            'a2.sourceA.vcf',
            'a2.sourceB.vcf',
            'a2.sourceC.vcf'
          ]

我怎样才能在bash中实现这一目标?

1 个答案:

答案 0 :(得分:2)

来自问题的另一个答案

unset a1 a2 a3

function push {
    local arr_name=$1
    shift
    if [[ $(declare -p "$arr_name" 2>&1) != "declare -a "* ]]
    then
        declare -g -a "$arr_name"
    fi
    declare -n array=$arr_name
    array+=($@)
}

for file in *.vcf; do [[ -e $file ]] && push "${file%%.*}" "$file"; done

(IFS=,;echo "${a1[*]}")
(IFS=,;echo "${a2[*]}")
(IFS=,;echo "${a3[*]}")

但是根据需要,对于模式来说可能就足够了

for file in a1.*.vcf; do ... ; done

最后$(ls )不得在for循环中使用,如其他答案所示。

Why you shouldn't parse the output of ls