Arrays 将文件列表作为值的关联数组…;

Arrays 将文件列表作为值的关联数组…;,arrays,bash,dictionary,hashtable,associative-array,Arrays,Bash,Dictionary,Hashtable,Associative Array,我在使用Bash的关联数组时遇到了一些问题:我正在寻找一种解决方案,将带有文件名的数组分配给关联数组 它应该是这样的: /Applications/Setup.app => ([0] = "/Applications/Setup.app/IDStore@2x.png" [1] = "/Applications/Setup.app/IDMessages@2x.png"

我在使用Bash的关联数组时遇到了一些问题:我正在寻找一种解决方案,将带有文件名的数组分配给关联数组

它应该是这样的:

/Applications/Setup.app => ([0] = "/Applications/Setup.app/IDStore@2x.png"
                            [1] = "/Applications/Setup.app/IDMessages@2x.png"
                            [2] = "/Applications/Setup.app/IDMusic New@2x.png")
声明字典/哈希表/关联数组不是问题:

declare -A Dictionary
要获取密钥,我将使用“readarray”和“find”组合:

但我想要这个:

/Applications/Setup.app/IDStore@2x.png
/Applications/Setup.app/IDMessages@2x.png
/Applications/Setup.app/IDMusic New@2x.png
有没有可能在Bash5.0.3中获得这项工作


目标是使用没有AWK/GRP/SED的大部分特征,所以它用BASH的内置命令运行。

< P>当用文件名填充数组时,考虑使用任何文件名中不存在的字符(作为分隔符)。[注意:按照当前编码,没有分隔符,因此文件名被挤在一起形成一条长线]

例如,假设文件名不包含换行符(
\n
),并假设
find
返回以下内容:

/Applications/Setup.app/IDStore@2x.png
/Applications/Setup.app/IDMessages@2x.png
/Applications/Setup.app/IDMusic New@2x.png
我们可以像这样填充阵列:

unset      Dictionary
declare -A Dictionary

App="/Applications/Setup.app"

# for sake of example, simulate find results by processing a list of files

for file in "/Applications/Setup.app/IDStore@2x.png" "/Applications/Setup.app/IDMessages@2x.png" "/Applications/Setup.app/IDMusic New@2x.png"
do
    Dictionary[${App}]+=$'\n'"${file}"     # use '\n' as delimiter
done

while IFS=$'\n' read -r line
do
    [[ -n "${line}" ]] &&                  # skip the initial '\n'
    printf "|%s|\n" "${line}"
done <<< "${Dictionary[@]}"

当使用文件名填充数组时,考虑使用任何文件名中不存在的字符(作为分隔符)。[注意:按照当前编码,没有分隔符,因此文件名被挤在一起形成一条长线]

例如,假设文件名不包含换行符(
\n
),并假设
find
返回以下内容:

/Applications/Setup.app/IDStore@2x.png
/Applications/Setup.app/IDMessages@2x.png
/Applications/Setup.app/IDMusic New@2x.png
我们可以像这样填充阵列:

unset      Dictionary
declare -A Dictionary

App="/Applications/Setup.app"

# for sake of example, simulate find results by processing a list of files

for file in "/Applications/Setup.app/IDStore@2x.png" "/Applications/Setup.app/IDMessages@2x.png" "/Applications/Setup.app/IDMusic New@2x.png"
do
    Dictionary[${App}]+=$'\n'"${file}"     # use '\n' as delimiter
done

while IFS=$'\n' read -r line
do
    [[ -n "${line}" ]] &&                  # skip the initial '\n'
    printf "|%s|\n" "${line}"
done <<< "${Dictionary[@]}"

<数组>,考虑这种方法:

[[ ${Applications[@]} ]] && {
    for i in "${!Applications[@]}"; do
        readarray -d '' "Files$i" < <(find "${Applications[$i]}" -iname "*.png" -type f -print0)
        Dictionary["${Applications[$i]}"]="Files$i"
    done
}

和检查

< PAR>数组,考虑这种方法:

[[ ${Applications[@]} ]] && {
    for i in "${!Applications[@]}"; do
        readarray -d '' "Files$i" < <(find "${Applications[$i]}" -iname "*.png" -type f -print0)
        Dictionary["${Applications[$i]}"]="Files$i"
    done
}

通过修改Ivan的漂亮答案来检查一下,怎么样:

declare -A Dictionary
readarray -d '' Applications < <(find "/Applications" -name "*.app" -print0)

for i in "${!Applications[@]}"; do
    readarray -d '' "Files$i" < <(find "${Applications[$i]}" -iname "*.png" -type f -print0)
    Dictionary["${Applications[$i]}"]="Files$i"
done

for key in "${!Dictionary[@]}"; do
    echo "$key => "
    declare -n ary="${Dictionary[$key]}"
    for j in "${!ary[@]}"; do
        echo "  [$j] = ${ary[j]}"
    done
done
结果将是:

/Applications/Foo.app => 
  [0] = Applications/Foo.app/foo1.png
  [1] = Applications/Foo.app/foo2.png
/Applications/Bar.app => 
  [0] = Applications/Bar.app/bar1.png
  [1] = Applications/Bar.app/bar2.png
/Applications/Setup.app => 
  [0] = Applications/Setup.app/IDStore@2x.png
  [1] = Applications/Setup.app/IDMusic New@2x.png
  [2] = Applications/Setup.app/IDMessages@2x.png

通过修改Ivan的好答案,可以:

declare -A Dictionary
readarray -d '' Applications < <(find "/Applications" -name "*.app" -print0)

for i in "${!Applications[@]}"; do
    readarray -d '' "Files$i" < <(find "${Applications[$i]}" -iname "*.png" -type f -print0)
    Dictionary["${Applications[$i]}"]="Files$i"
done

for key in "${!Dictionary[@]}"; do
    echo "$key => "
    declare -n ary="${Dictionary[$key]}"
    for j in "${!ary[@]}"; do
        echo "  [$j] = ${ary[j]}"
    done
done
结果将是:

/Applications/Foo.app => 
  [0] = Applications/Foo.app/foo1.png
  [1] = Applications/Foo.app/foo2.png
/Applications/Bar.app => 
  [0] = Applications/Bar.app/bar1.png
  [1] = Applications/Bar.app/bar2.png
/Applications/Setup.app => 
  [0] = Applications/Setup.app/IDStore@2x.png
  [1] = Applications/Setup.app/IDMusic New@2x.png
  [2] = Applications/Setup.app/IDMessages@2x.png

我唯一的想法是使用
jq
之类的工具,以类似JSON的格式存储列表。但实际上,如果需要二维数组,首先不应该使用
bash
。使用具有真实数据结构的编程语言。我唯一的想法是使用
jq
等工具,以JSON等格式存储列表。但实际上,如果需要二维数组,首先不应该使用
bash
。使用具有真实数据结构的编程语言。
/Applications/
├── Bar.app
│   ├── bar1.png
│   └── bar2.png
├── Foo.app
│   ├── foo1.png
│   └── foo2.png
└── Setup.app
    ├── IDMessages@2x.png
    ├── IDMusic New@2x.png
    └── IDStore@2x.png
/Applications/Foo.app => 
  [0] = Applications/Foo.app/foo1.png
  [1] = Applications/Foo.app/foo2.png
/Applications/Bar.app => 
  [0] = Applications/Bar.app/bar1.png
  [1] = Applications/Bar.app/bar2.png
/Applications/Setup.app => 
  [0] = Applications/Setup.app/IDStore@2x.png
  [1] = Applications/Setup.app/IDMusic New@2x.png
  [2] = Applications/Setup.app/IDMessages@2x.png