假设你有一个数组a=(foo 'bar baz')
有没有比这更明显的方法将命令/函数应用于每个数组元素并将结果字符串保存到另一个数组中:
b=()
for e in $a; do
b+=("$(my_cmd "$e")")
done
答案1
您始终可以为此声明一个函数:
map() {
local arrayname="$1" cmd="$2" i
shift 2
eval "$arrayname=()"
for i do
eval "$arrayname+=(\"\$($cmd)\")"
done
}
并用作:
$ a=(a '' bcd)
$ map b 'wc -c <<< "$i"' "$a[@]"
$ echo $b
2 1 4
答案2
如果您事先知道该命令对数组元素执行的操作,那么您可以使用参数扩展标志(请参阅man zshexpn
)指导zsh
如何将命令输出调整为数组。
例子
假设一个数组a
包含文件名,每个文件仅包含一行文本:
$ a=(foo 'bar baz')
$ cat foo
A
$ cat 'bar baz'
B C
现在为了论证起见,我们假设该命令只是将文件的内容cat
放入数组中。b
在这种情况下,我们可以简单地写而不是循环
b=(${(f)"$(cat "${a[@]}")"})
where(f)
将 的结果分割cat
成换行符处的分隔词。
结果如预期:
$ echo "${b[1]}"
A
$ echo "${b[2]}"
B C
根据实际情况,您可以使用 flag 拆分不同的字符ps:<character>:
。其中一些如上(ps:\n:)
例中的换行符或 NULL 字符分别(ps:\0:)
具有简写:(f)
和(0)
。
答案3
你可以这样做:
eval "b=(" '"$(cmd "$a['{1..$#a}']")"' ")"
但这不太清晰。
答案4
只是注意一下:
你可以用以下方法缩短它:
for e ($a) b+=("$(my_cmd "$e")")
请注意,$a
循环遍历非空元素。要循环所有元素,它是"$a[@]"
.