如何使用文件行填充bash数组

时间:2016-04-19 02:56:10

标签: arrays bash shell scripting

从文件中填充数组应该是基本的,但我无法使其工作。

    #!/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 ''

我在这里做错了什么?

1 个答案:

答案 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"