arrays - bash 在循环中分配给数组索引时遇到问题

标签 arrays bash

我可以让它在 ksh 中工作,但不能在 bash 中工作,这真的让我抓狂。 希望这是我忽略的显而易见的事情。

我需要运行一个外部命令,其中输出的每一行都将存储在一个数组索引中。

这个简化的示例看起来像是在循环中正确设置了数组,但是在循环完成后那些数组赋值就消失了吗?好像循环完全被当作一个外壳?

垃圾.txt

this is a
test to see
if this works ok

testa.sh

#!/bin/bash

declare -i i=0
declare -a array

echo "Simple Test:"
array[0]="hello"
echo "array[0] = ${array[0]}"

echo -e "\nLoop through junk.txt:"
cat junk.txt | while read line
do
    array[i]="$line"
    echo "array[$i] = ${array[i]}"
    let i++
done

echo -e "\nResults:"
echo "       array[0] = ${array[0]}"
echo " Total in array = ${#array[*]}"
echo "The whole array:"
echo ${array[@]}

输出

Simple Test:
array[0] = hello

Loop through junk.txt:
array[0] = this is a
array[1] = test to see
array[2] = if this works ok

Results:
      array[0] = hello
Total in array = 1
The whole array:
hello

因此在循环中,我们分配 array[i] 并回显验证它。 但在循环之后,我回到了包含“hello”但没有其他元素的数组 [0]。

bash 3、4 和不同平台上的结果相同。

最佳答案

因为您的 while 循环在管道中,所以循环体中的所有变量赋值对于执行循环的子 shell 都是本地的。 (我相信 ksh 不会在子 shell 中运行该命令,这就是您在 bash 中遇到问题的原因。)改为这样做:

while read line
do
    array[i]="$line"
    echo "array[$i] = ${array[i]}"
    let i++
done < junk.txt

您很少(如果有的话)想要使用cat单个 文件通过管道传输到另一个命令;请改用输入重定向。

更新:由于您需要从命令而不是文件运行,另一个选项(如果可用)是进程替换:

while read line; do
...
done < <( command args ... )

如果进程替换不可用,您将需要输出到一个临时文件并重定向来自该文件的输入。

如果您使用的是 bash 4.2 或更高版本,您可以在循环之前执行这两个命令,并且原始的管道进入循环将起作用,因为 while 循环是最后命令正在筹备中。

set +m    # Turn off job control; it's probably already off in a non-interactive script
shopt -s lastpipe
cat junk.txt | while read line; do ...; done

更新 2:这是一个基于 user1596414 评论的无循环解决方案

array[0]=hello
IFS=$'\n' array+=( $(command) )

命令的输出仅根据换行符拆分为单词(因此每一行都是一个单独的单词),并将生成的每槽行数组附加到原始数组。如果您只使用循环来构建数组,这是非常好的。它也可能被修改以适应少量的每行处理,模糊地类似于 Python 列表理解。

关于arrays - bash 在循环中分配给数组索引时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56729396/

相关文章:

c# - C#中迭代器和数组的区别

c - 如何扫描多个值并添加到数组?

javascript - Angularjs:如何 ng-repeat 具有也是数组的字段的对象数组?

php - 如何将数据库中的信息添加到现有的对象数组中?

bash - 如何在 bash printf 的格式字符串中包含破折号?

linux - linux文件上的退格问题

arrays - Bash 中的数组 : Displaying all elements of array

linux - 如何通过用户数据在 EC2 实例上设置环境变量

Linux:如果文件路径名已存在于输入文件中,则跳过 grepping 文件

php - 使用 procmail 调用 php 脚本