从文件中填充数组应该是基本的,但我无法使其工作。
#!/bin/bash
declare -a a
i=0
cat "file.txt" | while read line; do
a[$i]="$line"
i=$(($i + 1))
done
echo "${a[0]}"
这会打印一个空行。对于包含行" Foo"和" Bar",这里是bash -x的输出:
+ declare -a a
+ i=0
+ cat file.txt
+ read line
+ a[$i]=Foo
+ i=1
+ read line
+ a[$i]=Bar
+ i=2
+ read line
+ echo ''
我甚至无法让readarray内置工作:
#!/bin/bash
declare -a b
cat "file.txt" | readarray b
echo "${b[0]}"
+ declare -a b
+ cat file.txt
+ readarray b
+ echo ''
我在这里做错了什么?
答案 0 :(得分:3)
这是一个基本的bash
陷阱:默认情况下,管道的所有段都在子shell 中执行,这意味着当这些子壳终止时,它们创建的任何变量都将超出范围(当前的shell不会看到它们。)
根据您使用的bash
版本,您有两种选择:
[Bash v4.2 +]在使用管道之前执行shopt -s lastpipe
以确保 last 管道段在当前shell中运行。
使用输入重定向(<
)而不是管道(或者,在更复杂的情况下,使用流程替换(<(...)
)来确保您的while
循环不会在子shell中运行:
a=()
while IFS= read -r line; do
a+=( "$line" )
# ...
done < "file.txt"
在从文件中读取行的简单情况下,您可以将直接读入数组(在此示例中为"${a[@]}"
):
Bash 4.x:
readarray -t a < "file.txt"
早期版本:
IFS=$'\n' read -r -d '' -a a < "file.txt"