有没有办法在不遍历所有元素的情况下打印整个数组([key]=value)?
假设我创建了一个包含一些元素的数组:
declare -A array
array=([a1]=1 [a2]=2 ... [b1]=bbb ... [f500]=abcdef)
Run Code Online (Sandbox Code Playgroud)
我可以打印回整个数组
for i in "${!array[@]}"
do
echo "${i}=${array[$i]}"
done
Run Code Online (Sandbox Code Playgroud)
但是,似乎 bash 已经知道如何一次性获取所有数组元素 - 键${!array[@]}和值${array[@]}。
有没有办法让 bash 在没有循环的情况下打印这个信息?
编辑:
typeset -p array这样做!
但是,我无法在一次替换中同时删除前缀和后缀:
a="$(typeset -p array)"
b="${a##*(}"
c="${b%% )*}"
Run Code Online (Sandbox Code Playgroud)
有没有更干净的方法来获取/打印输出的键=值部分?
一些类似 Bourne 的 shell 支持关联数组:(ksh93自 1993 年以来)、zsh(自 1998 年以来)、bash(自 2009 年以来),尽管 3 之间的行为存在一些差异。
一个常见的用途是计算某些字符串的出现次数。
但是,我发现以下内容:
typeset -A count(( count[$var]++ ))
对某些值不起作用$var,我听说如果 的内容处于或可能处于攻击者的控制之下,它甚至会构成任意命令执行漏洞$var。
这是为什么?有问题的价值观是什么?我该如何解决它?
我看到了在 shell 脚本中实现关联数组的技巧。例如,print array["apples"]可以将脚本编写为echo \$array$keywhere key=apples。
但是,没有提到如何生成键来迭代数组。我能想到的唯一方法是将键存储在一个由空格分隔的变量中,这样我就可以使用 for 循环来遍历数组。
那么,是否有其他方法可以存储密钥以备后用?
在脚本中,我有一个关联数组,例如:
declare -A VARS=( ["key1"]="value1" ["key2"]="value" )
Run Code Online (Sandbox Code Playgroud)
是否有一个命令可以将其转换为表单中的参数列表
--key1=value1 --key2=value2
Run Code Online (Sandbox Code Playgroud)
无需手动重写
--key1="${VARS[key1]}" --key2="${VARS[key2]}"
Run Code Online (Sandbox Code Playgroud)
我想到的用例是将数组作为参数列表传递给脚本,例如
my_script.sh $(to_param_list $VARS)
Run Code Online (Sandbox Code Playgroud)
为了扩展我对@Kusalananda 答案所做的评论,我的确切用例如下:我有一个脚本,用于使用 makeself 构建自解压安装程序,并且该脚本接收一些要分开的参数:
然后脚本会像这样构建安装程序:
to_param_list installer_param_list installer_param_array
./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "${installer_param_list[@]}"
Run Code Online (Sandbox Code Playgroud)
但是,我已经使用包内的一个非常简单的安装程序脚本测试了参数传递:
while ! -z "$1" ; do
echo "$1"
shift
done
Run Code Online (Sandbox Code Playgroud)
并传递一个数组,如:
installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )
Run Code Online (Sandbox Code Playgroud)
导致此输出:
--upgrade-to=19.3.0
--upgrade-from=19
.2.0
Run Code Online (Sandbox Code Playgroud) 解析内容的细节:散列和等号。其他一切都是奖金。
属性文件内容示例:
# comment
a=value-a
b=http://prefix.suffix:8080/?key=value
c=password_with\\backslash-and=equals
Run Code Online (Sandbox Code Playgroud)
我希望从该文件中构造这个 bash 关联数组:
declare -A props='(
[a]="value-a"
[b]="http://prefix.suffix:8080/?key=value"
[c]="password_with\\backslash-and=equals" )'
Run Code Online (Sandbox Code Playgroud)
(declare -p该关联数组的预期输出,注意${props[c]}只包含一个反斜杠,"\\"是'\')。
假设我有一个关联数组bash,
declare -A hash
hash=(
["foo"]=aa
["bar"]=bb
["baz"]=aa
["quux"]=bb
["wibble"]=cc
["wobble"]=aa
)
Run Code Online (Sandbox Code Playgroud)
其中键和值对我来说都是未知的(实际数据是从外部来源读取的)。
我如何创建与相同值对应的键数组,以便我可以在所有唯一值的循环中执行
printf 'Value "%s" is present with the following keys: %s\n' "$value" "${keys[*]}"
Run Code Online (Sandbox Code Playgroud)
并获得输出(不一定按此顺序)
Value "aa" is present with the following keys: foo baz wobble
Value "bb" is present with the following keys: bar quux
Value "cc" is present with the following keys: wibble
Run Code Online (Sandbox Code Playgroud)
重要的一点是键作为单独的元素存储在keys数组中,因此不需要从文本字符串中解析出来。
我可以做类似的事情
declare -A seen
seen=()
for value in "${hash[@]}"; do
if [ -n "${seen[$value]}" ]; then
continue
fi …Run Code Online (Sandbox Code Playgroud) I know the -v switch can be used to awk on the command line to set the value for a variable.
Is there any way to set values for awk associative array elements on the command line?
Something like:
awk -v myarray[index]=value -v myarray["index two"]="value two" 'BEGIN {...}'
Run Code Online (Sandbox Code Playgroud) 我需要将命令的输出放入关联数组中。
例如:
dig mx +short google.com
Run Code Online (Sandbox Code Playgroud)
将返回:
20 alt1.aspmx.l.google.com.
40 alt3.aspmx.l.google.com.
50 alt4.aspmx.l.google.com.
10 aspmx.l.google.com.
30 alt2.aspmx.l.google.com.
Run Code Online (Sandbox Code Playgroud)
如何使用优先级 (10,20,...) 作为键和记录 (aspmx.l.google.com.) 作为值创建关联数组?
我声明一个关联数组:
declare -A array=([a]=blue [b]=red [c]=yellow)
Run Code Online (Sandbox Code Playgroud)
现在我可以做:
echo ${array[@]} --> blue red yellow
Run Code Online (Sandbox Code Playgroud)
或者
echo ${array[b]} --> red
Run Code Online (Sandbox Code Playgroud)
或者
echo ${!array[@]} --> a b c
Run Code Online (Sandbox Code Playgroud)
现在我只想知道与red值关联的键。有没有办法只检测单个密钥?
$ bash -version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
Run Code Online (Sandbox Code Playgroud)
考虑以下 shell 脚本:
#!/bin/bash
declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )
for key in "${!PROVS[@]}" ; do \
touch "foo_${key}_${PROVS[${key}]}" ; \
done
Run Code Online (Sandbox Code Playgroud)
我正在尝试在 Makefile 中执行等效操作:
SHELL := /bin/bash
.PHONY: foo
foo:
declare -A PROVS=( ["NL"]=10 ["PE"]=11 ["NS"]=12 ["NB"]=13 ["QC"]=24 ["ON"]=35 ["MB"]=46 ["SK"]=47 ["AB"]=48 ["BC"]=59 ["YK"]=60 ["NT"]=61 ["NU"]=62 )
for key in "$${!PROVS[@]}" ; do \
touch "foo_$${key}_$${PROVS[$${key}]}" ; \
done
Run Code Online (Sandbox Code Playgroud)
我 …