在Bash中从文本文件创建数组

use*_*414 71 arrays bash scripting loops variable-assignment

脚本获取URL,解析所需的字段,并将其输出重定向以保存在文件file.txt中.每次找到字段时,输出都会保存在新行中.

file.txt的

A Cat
A Dog
A Mouse 
etc... 
Run Code Online (Sandbox Code Playgroud)

我想file.txt在一个新脚本中从中创建一个数组,其中每一行都是数组中自己的字符串变量.到目前为止,我尝试过:

#!/bin/bash

filename=file.txt
declare -a myArray
myArray=(`cat "$filename"`)

for (( i = 0 ; i < 9 ; i++))
do
  echo "Element [$i]: ${myArray[$i]}"
done
Run Code Online (Sandbox Code Playgroud)

当我运行这个脚本时,空格导致单词被分割而不是获取

期望的输出

Element [0]: A Cat 
Element [1]: A Dog 
etc... 
Run Code Online (Sandbox Code Playgroud)

我最终得到这个:

实际输出

Element [0]: A 
Element [1]: Cat 
Element [2]: A
Element [3]: Dog 
etc... 
Run Code Online (Sandbox Code Playgroud)

如何调整下面的循环,使每行上的整个字符串与数组中的每个变量一一对应?

gle*_*man 85

使用mapfile命令:

mapfile -t myArray < file.txt
Run Code Online (Sandbox Code Playgroud)

错误正在使用for- 循环文件的惯用方法是:

while IFS= read -r line; do echo ">>$line<<"; done < file.txt
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅BashFAQ/005.

  • Bash 4现在已经有5年了.升级. (10认同)
  • 在4.x之前的bash版本中不存在mapfile (9认同)
  • 尽管 bash 4 于 2009 年发布,@ericslaw 的评论仍然具有相关性,因为许多机器仍然附带 bash 3.x(并且不会升级,只要 bash 在 GPLv3 下发布)。如果您对便携性感兴趣,请务必注意 (6认同)
  • 由于这被提升为规范的q&a,你还可以包括链接中提到的内容:`IFS = read -r; 做行+ =("$ REPLY"); 完成<文件`. (4认同)
  • 问题不是开发人员无法安装升级版本,而是开发人员应该意识到,使用“ mapfile”的脚本在没有其他步骤的情况下不会在许多机器上按预期运行。在可预见的将来,@ ericslaw macs将继续提供bash 3.2.57。较新的版本使用的许可证要求Apple共享或允许他们不想共享或允许的内容。 (4认同)

cod*_*ter 16

mapfilereadarray(它们是同义词)在Bash版本4及更高版本中可用.如果您有旧版本的Bash,则可以使用循环将文件读入数组:

arr=()
while IFS= read -r line; do
  arr+=("$line")
done < file
Run Code Online (Sandbox Code Playgroud)

如果文件的最后一行有不完整(缺少换行符),您可以使用此替代方法:

arr=()
while IFS= read -r line || [[ "$line" ]]  do
  arr+=("$line")
done < file
Run Code Online (Sandbox Code Playgroud)

有关:


Jah*_*hid 7

你也可以这样做:

oldIFS="$IFS"
IFS=$'\n' arr=($(<file))
IFS="$oldIFS"
echo "${arr[1]}" # It will print `A Dog`.
Run Code Online (Sandbox Code Playgroud)

注意:

文件名扩展仍然存在.例如,如果有一行文字*,它将扩展到当前文件夹中的所有文件.因此,只有当您的文件没有这种情况时才使用它.


Cam*_*mer 6

使用 mapfile 或 read -a

始终使用shellcheck检查您的代码。它通常会给你正确的答案。在这种情况下,SC2207涵盖了将具有空格分隔或换行分隔值的文件读取到数组中。

不要这样做

array=( $(mycommand) )
Run Code Online (Sandbox Code Playgroud)

值由换行符分隔的文件

mapfile -t array < <(mycommand)
Run Code Online (Sandbox Code Playgroud)

值以空格分隔的文件

IFS=" " read -r -a array <<< "$(mycommand)"
Run Code Online (Sandbox Code Playgroud)

shellcheck 页面将为您提供为什么这被认为是最佳实践的基本原理。


Pra*_*shi 5

您可以简单地从文件中读取每一行并将其分配给一个数组。

#!/bin/bash
i=0
while read line 
do
        arr[$i]="$line"
        i=$((i+1))
done < file.txt
Run Code Online (Sandbox Code Playgroud)

  • 你如何访问数组? (2认同)