【问题标题】:How to populate a bash array with a file's lines如何用文件的行填充 bash 数组
【发布时间】:2016-04-19 02:56:09
【问题描述】:

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

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

我在这里做错了什么?

【问题讨论】:

    标签: arrays bash shell scripting


    【解决方案1】:

    这是一个基本的bash 陷阱:默认情况下,管道的所有段都在 subshel​​ls 中执行,这意味着它们创建的任何变量都将在这些子 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[@]}"):

    • 重击 4.x:

      • readarray -t a &lt; "file.txt"
    • 早期版本:

      • IFS=$'\n' read -r -d '' -a a &lt; "file.txt"

    【讨论】:

    • 这肯定会非常方便。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    相关资源
    最近更新 更多