将文件中的行读入 Bash 数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11393817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:24:02  来源:igfitidea点击:

Read lines from a file into a Bash array

arraysbash

提问by Homunculus Reticulli

I am trying to read a file containing lines into a Bash array.

我正在尝试将包含行的文件读入 Bash 数组。

I have tried the following so far:

到目前为止,我已经尝试了以下方法:

Attempt1

尝试 1

a=( $( cat /path/to/filename ) )

Attempt2

尝试 2

index=0
while read line ; do
    MYARRAY[$index]="$line"
    index=$(($index+1))
done < /path/to/filename

Both attempts only return a one element array containing the first line of the file. What am I doing wrong?

两次尝试都只返回一个包含文件第一行的单元素数组。我究竟做错了什么?

I am running bash 4.1.5

我正在运行 bash 4.1.5

采纳答案by nhed

Latest revision based on comment from BinaryZebra's commentand tested here. The addition of command evalallows for the expression to be kept in the present execution environment while the expressions before are only held for the duration of the eval.

基于BinaryZebra 评论的最新修订版, 并在此处进行了测试。添加command eval允许表达式保留在当前执行环境中,而之前的表达式仅在 eval 期间保留。

Use $IFS that has no spaces\tabs, just newlines/CR

使用没有空格\制表符,只有换行符/CR 的 $IFS

$ IFS=$'\r\n' GLOBIGNORE='*' command eval  'XYZ=($(cat /etc/passwd))'
$ echo "${XYZ[5]}"
sync:x:5:0:sync:/sbin:/bin/sync

Also note that you may be setting the array just fine but reading it wrong - be sure to use both double-quotes ""and braces {}as in the example above

另请注意,您可能将数组设置得很好,但读错了 - 请务必使用双引号""和大括号,{}如上例所示



Edit:

编辑:

Please note the many warnings about my answer in comments about possible glob expansion, specifically gniourf-gniourf's commentsabout my prior attempts to work around

请注意在关于可能的 glob 扩展的评论中关于我的回答的许多警告,特别是gniourf-gniourf关于我之前尝试解决的评论

With all those warnings in mind I'm still leaving this answer here (yes, bash 4 has been out for many years but I recall that some macs only 2/3 years old have pre-4 as default shell)

考虑到所有这些警告,我仍然把这个答案留在这里(是的,bash 4 已经推出多年,但我记得一些只有 2/3 岁的 mac 将 pre-4 作为默认 shell)

Other notes:

其他注意事项:

Can also follow drizzt's suggestion below and replace a forked subshell+cat with

也可以按照下面的 drizzt 的建议,将分叉的 subshel​​l+cat 替换为

$(</etc/passwd)

The other option I sometimes use is just set IFS into XIFS, then restore after. See also Sorpigal's answerwhich does not need to bother with this

我有时使用的另一个选项是将 IFS 设置为 XIFS,然后再恢复。另请参阅Sorpigal 的答案,无需为此烦恼

回答by chepner

The readarraycommand(also spelled mapfile) was introduced in bash 4.0.

readarray命令(也拼mapfile)在bash 4.0中引入的。

readarray -t a < /path/to/filename

回答by sorpigal

The simplest way to read each line of a file into a basharray is this:

将文件的每一行读入bash数组的最简单方法是:

IFS=$'\n' read -d '' -r -a lines < /etc/passwd

Now just index in to the array linesto retrieve each line, e.g.

现在只需索引到数组lines以检索每一行,例如

printf "line 1: %s\n" "${lines[0]}"
printf "line 5: %s\n" "${lines[4]}"

# all lines
echo "${lines[@]}"

回答by Karanjot

One alternate way if file contains strings without spaces with 1string each line:

如果文件包含不带空格的字符串,每行 1 个字符串,则另一种方法是:

fileItemString=$(cat  filename |tr "\n" " ")

fileItemArray=($fileItemString)

Check:

查看:

Print whole Array:

打印整个数组:

${fileItemArray[*]}

Length=${#fileItemArray[@]}

回答by Atttacat

Your first attempt was close. Here is the simplistic approach using your idea.

你的第一次尝试很接近。这是使用您的想法的简单方法。

file="somefileondisk"
lines=`cat $file`
for line in $lines; do
        echo "$line"
done

回答by Gopesh Bharadwaj

#!/bin/bash
IFS=$'\n' read  -d'' -r -a inlines  < testinput
IFS=$'\n' read  -d'' -r -a  outlines < testoutput
counter=0
cat testinput | while read line; 
do
    echo "$((${inlines[$counter]}-${outlines[$counter]}))"
    counter=$(($counter+1))
done
# OR Do like this
counter=0
readarray a < testinput
readarray b < testoutput
cat testinput | while read myline; 
do
    echo value is: $((${a[$counter]}-${b[$counter]}))
    counter=$(($counter+1))
done