繁体   English   中英

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

[英]Creating an array from a text file in Bash

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

文件.txt

A Cat
A Dog
A Mouse 
etc... 

我想获取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

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

期望输出

Element [0]: A Cat 
Element [1]: A Dog 
etc... 

我最终得到这个:

实际产量

Element [0]: A 
Element [1]: Cat 
Element [2]: A
Element [3]: Dog 
etc... 

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

使用mapfile命令:

mapfile -t myArray < file.txt

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

while IFS= read -r line; do echo ">>$line<<"; done < file.txt

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

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

arr=()
while IFS= read -r line; do
  arr+=("$line")
done < file

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

arr=()
while IFS= read -r line || [[ "$line" ]]; do
  arr+=("$line")
done < file

有关的:

你也可以这样做:

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

笔记:

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

使用 mapfile 或 read -a

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

不要这样做

array=( $(mycommand) )

值由换行符分隔的文件

mapfile -t array < <(mycommand)

值以空格分隔的文件

IFS=" " read -r -a array <<< "$(mycommand)"

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

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

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

这个答案说使用

mapfile -t myArray < file.txt

如果您出于任何原因想在 bash < 4.x 上使用mapfile ,我为mapfile制作了一个垫片 如果您使用的是 bash >= 4.x,它会使用现有的mapfile命令

目前,只有选项-d-t有效。 但这对于上面的命令应该足够了。 我只在 macOS 上测试过。 在 macOS Sierra 10.12.6 上,系统 bash 是3.2.57(1)-release 所以垫片可以派上用场。 您也可以使用自制软件更新您的 bash,自己构建 bash 等。

它使用这种技术在一个调用堆栈中设置变量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM