在 bash 脚本中,循环遍历 bash 数组以输入二进制文件

在 bash 脚本中,循环遍历 bash 数组以输入二进制文件

我正在运行 bash。

  • 假设我有一个mybinary接受交互式用户输入的二进制文件。
  • 假设mybinary将与会者姓名作为输入,直到用户键入q并按下Enterq表示“退出”)。
  • <<EOF我可以通过/包围输入来自动化 bash 脚本中的输入过程EOF。例如,假设我想从数组输入预定义的用户输入myarray。我可以:
#!/bin/bash

myarray=("Alice" "Bob" "Charlie" "q") # q quits the binary

mybinary -f inputfile.txt -o outputfile.txt<<EOF
${myarray[0]}
${myarray[1]}
${myarray[2]}
${myarray[3]}
EOF

我测试了上面的内容,并且有效。但是如果有数百个(字符串)元素,${myarray[X]}则为每个索引键入是很费力的。myarraymyarray

如何修改上面的 bash 脚本以循环遍历myarray

以下内容将不起作用,因为fordodone部分将被视为 的输入mybinary

#!/bin/bash

myarray=("Alice" "Bob" "Charlie" "q") # q quits the binary

mybinary -f inputfile.txt -o outputfile.txt<<EOF
for element in "${myarray[@]}"
do
${myarray[0]}
${myarray[1]}
${myarray[2]}
${myarray[3]}
done
EOF

此外,我不能简单地放置for循环大约调用mybinary,因为我不想多次调用mybinary那么如何循环遍历数组以使用数组的元素作为输入mybinary

答案1

您可以printf在数组中的每个条目之后添加换行符:

myarray=("Alice" "Bob" "Charlie" "q")

mybinary -f inputfile.txt -o outputfile.txt<<EOF
$(printf '%s\n' "${myarray[@]}")
EOF

正如 didal24 和 Steeldriver 指出的那样,您还可以使用管道而不是此处文档:

printf '%s\n' "${myarray[@]}" | mybinary -f inputfile.txt -o outputfile.txt

答案2

如果我很了解您的需求:

#!/bin/bash

myarray=("Alice" "Bob" "Charlie" "q") # q quits the binary

mybinary -f inputfile.txt -o outputfile.txt < <(printf '%s\n' "${myarray[@]}")

如果您的二进制文件编码良好,则应该STDIN透明地处理它。

答案3

要在 zsh 中每行打印一个数组的元素,您可以执行以下操作:

print -rC1 -- "$array[@]"

或者:

print -rNC1 -- "$array[@]"

用于 NUL 分隔的记录而不是行。

print -rC1 -- $array只会打印非空元素)。

bash有一个print内置函数(最初来自 ksh),但仅作为可选的可加载内置函数,并且不支持该-C选项(也不支持-N)。

printf '%s\n' "${array[@]}"对于空数组无法正常工作,因为它打印一个空行(就好像数组有一个空元素)而不是根本不打印任何行。

bash(或一般的 POSIX shells)中的常见方法是定义一些辅助函数:

println() { [ "$#" -eq 0 ] || printf '%s\n' "$@"; }
print0() { [ "$#" -eq 0 ] || printf '%s\0' "$@"; }

然后,你可以这样做:

println "${array[@]}" q | your-cmd

¹ 请注意,某些 POSIX shell(主要是 ksh88 和一些基于 pdksh 的 shell)没有printf内置功能,因此无法输出大型列表,因为您很快就会达到参数大小的限制传递给外部命令。

相关内容