对 ksh 中数组中的每个元素执行一个函数

Posted

技术标签:

【中文标题】对 ksh 中数组中的每个元素执行一个函数【英文标题】:perform a function on each element in an array in ksh 【发布时间】:2021-03-19 07:11:51 【问题描述】:

我的脚本前一部分有一个变量,该变量是 greped/sed/cut/sort/uniq 从前一个脚本的多行输出到我需要的,n 数量的数字数据

echo "$array"
12345
54321
01234

据我了解,我可以将这一列数字视为一个数组

项目的数量可以从只有 1 个到可能多达 6 个不等。我已经验证没有空格可能会丢掉东西。

从这里我尝试

for element in "array[@]"; do

foo $anothervar "$element"

bar $anothervar "$element"

done

但我最终得到了变量中的所有值。

foo $anothervar 12345 54321 01234

(请注意,$anothervar 仅用于演示目的,它实际上是 $1,因此该 var 的 shell 扩展 不一定是问题)

等等。如果我

#with double quotes
echo "$element"
12345
54321
01234

#without quotes
echo $element
12345 54321 01234

所以我不能对这些数据做任何迭代。我可以将此变量视为一个数组并且必须对 var 执行另一个操作,然后才能将其输入到 for 循环,这是我的错误吗?

我的期望

foo $anothervar "$element"
*output of $anothervar 12345*

bar $anothervar "$element"
*output of $anothervar 12345*

foo $anothervar "$element"
*output of $anothervar 54321*

bar $anothervar "$element"
*output of $anothervar 54321*

etc etc

这是 AIX 上的 ksh88,根据我的研究,这应该可以工作,除非可能涉及 ksh88 与更高版本?我对数组很陌生,但对 shell 脚本并不陌生,尽管我几乎不会称自己为专家。提前感谢您提供的任何帮助。

【问题讨论】:

您使用的是哪个,var=...array=( ... ... ...) 或 ??编辑您的 Q 以显示一组完全可测试的数据,以及您所需的输出/操作(是的,您已经接近了)。我会尝试for elem in $var[@] ; do ...`(没有dbl-quotes)。祝你好运。 您已经在 3 个不同的变量中显示了数据 ...$var(不是数组)...array[@](看起来像数组引用,但不知道 array[@] 中的实际内容) ... $element (不是数组);请清理您帖子中的不一致之处;回到包含数据的单个变量后,将typeset -p <variable_name> 的输出添加到您的问题中,以便我们准确地查看变量中的内容及其结构 感谢您指出这一点。我正在尝试从专有代码制作通用 sn-ps 以提出问题 将您的代码复制/粘贴到shellcheck.net 并修复标记的所有错误。请务必将#!/bin/ksh 或#!/bin/ksh93` 作为第一行。用你最好的代码和所需的输出更新你的 Q。祝你好运。 换句话说:请提供minimal reproducible example 【参考方案1】:

我没有可用于实验的 ksh88,但使用 ksh93(我正在使用 Version AJM 93u+ 2012-08-01)这将产生类似于您的数据的内容:

$ val=` for ((ii=1; ii<4; ii++))
do
echo $ii
done`

如果我以两种不同的方式回应这一点,我会得到你所看到的开始:

$ echo $val
1 2 3
$ echo "$val"
1
2
3

现在,我添加一个函数

$ function foo 
> echo $1 $2
> 

我可以循环遍历这些值,一次一个:

$ for xx in $val
> do
> foo foo $xx
> done
foo 1
foo 2
foo 3

或者全部一起(这不是你想要的):

$ for xx in "$val"
> do
> foo foo $xx
> done
foo 1

嘿,我的其余值发生了什么变化?仔细观察,通过在 $val 周围添加引号,我们将所有值一次分配给 xx。我们可以通过以下方式更清楚地看到这一点:

for xx in "$val"
do
foo foo $xx
echo "The value of xx=$xx"
echo "or in hex:"
echo "The value of xx=$xx" | xxd -g 1
done
foo 1
The value of xx=1
2
3
or in hex:
0000000: 54 68 65 20 76 61 6c 75 65 20 6f 66 20 78 78 3d  The value of xx=
0000010: 31 0a 32 0a 33 0a                                1.2.3.

xx 的单个值是1\n2\n3\n(\n 是换行符),当我们将它传递给 foo 函数时,它只看到第一个值 1。

如果我们稍微更新一下,

for xx in "$val"
do
foo foo "$xx"
done
foo 1 2 3

我们看到单独的值被传递给函数。由于该函数没有引用 $2 参数,因此我们看不到换行符。

这能回答你的问题吗?

我建议您使用 ksh93,因为您不想落后于时代 27 年。从 1993 年开始,David Korn 对 ksh 进行了相当大的更新,这些更新值得在 AIX 上输入 ksh93 而不仅仅是 ksh。

【讨论】:

【参考方案2】:

您使用的是哪个,var=... 或 array=( ... ... ...) 或 ??编辑您的 Q 以显示一组完全可测试的数据,以及您所需的输出/操作(是的,您已经接近了)。我会在 $var[@] 中尝试 elem ;做 ...`(没有 dbl 引号)。祝你好运。

谢谢@shellter,双引号确实是问题所在。我假设,因为我在以前的答案中发现它必须是更高版本的 ksh 的有效语法,但今天你解决了我的问题,我感谢所有提供建议的人。

【讨论】:

以上是关于对 ksh 中数组中的每个元素执行一个函数的主要内容,如果未能解决你的问题,请参考以下文章

Swift高阶函数-MapFilterReduce

Swift高阶函数-MapFilterReduce

使用数组中的每个元素调用集合返回函数

数组Api .map()的使用

前端随心记---------函数

数组的some()方法entries()方法