我试图创建一个循环输入并执行命令的函数——不管它们是如何分隔的。
function loop {
# Args
# 1: Command
# 2: Inputs
for input in "$2" ; do
$1 $input
done
}
declare -a arr=("1" "2" "3")
$ loop echo "$arr[@]"
1
$ loop echo 1 2 3
1
$ loop echo $arr
1
但是根据这个答案,for .. in ..
适用于数组:
for item in "${arr[@]}" ; do
echo "$item"
done
它也适用于空格分隔的值:
for item in 1 2 3 ; do
echo "$item"
done
简而言之,我如何在传递参数时获得"${arr[@]}"
效果1 2 3
。
是否可以将这种循环概念扩展到任何类型的分隔项,例如\n
像文件这样的分隔内容?在 Python 中我们有一个概念iterators
,在 bash 中是否有类似的东西?
您没有正确调用数组。
$arr
只会扩展到数组中的第一个元素,并将扩展到第一个元素并附加$arr[@]
文字字符串。[@]
要调用数组的所有元素,请使用:
"${arr[@]}"
您遇到的另一个问题是
$2
仅包含第二个位置参数,您尝试在其中迭代第 3、第 4、第 5 等。它们都将存储在$@
.为了实现您的目标,您可以执行以下操作:
这将设置
command
为第一个位置参数,然后移位,以便$@
可以用来循环剩余的参数。然后你只需要正确调用数组:如果您希望此函数能够接受各种分隔符,您可以执行以下操作:
这意味着您必须通过第二个参数指定正在使用的分隔符,例如:
但是,这有一些错误(如果您指定自定义分隔符,它仍将由空格分隔)
您的代码中有语法错误。在对您的
loop
函数的调用中,使用"${arr[@]}"
将arr
数组扩展为每个元素的列表,单独引用。这就是您在for
显示的循环中所做的事情,这也是您在调用函数时应该做的事情:另请注意,您的函数需要挑选出您传递的命令的名称,然后它需要循环其剩余的参数:
在这里,我们将第一个参数分配给变量
cmd
(这是命令),然后我们shift
将此参数从参数列表中删除。参数列表现在只包含要循环的字符串。然后循环依次为每个剩余的参数调用命令。
这以有限的方式复制了该
xargs
实用程序的用途,并且可以使用该实用程序重新实现该功能(除非您希望其中一个参数包含嵌入的换行符,在这种情况下您必须将选项调整为xargs
) :由于该
xargs
实用程序希望通过标准输入传递数据,因此我们使用它来安排并在其自己的一行上printf
打印给定的每个参数(同时告诉使用 为每个换行符分隔的参数调用给定的实用程序一次)。loop
xargs
-L 1
这将允许我们使用 的某些实现的其他功能
xargs
,例如使用-P n
wheren
是一些并行运行的进程来启动并行进程。测试:
您的循环与 GNU Parallel 非常相似:
-j1
强制一次运行一个作业。