将文件中的行读入Bash数组

我试图将包含行文件读入Bash数组。

到目前为止,我尝试了以下几种方法:

Attempt1

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

Attempt2

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

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

我运行bash 4.1.5

564455 次浏览

最新修订基于BinaryZebra的评论测试在这里command eval的添加允许表达式被保留在当前的执行环境中,而之前的表达式仅在eval.

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

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

还要注意,你可能设置数组很好,但读错了——一定要使用双引号""和大括号{},就像上面的例子一样


编辑:

请注意,关于我的答案在评论中可能的glob扩展的许多警告,特别是gniourf-gniourf的评论关于我以前试图解决的问题

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

另注:

也可以按照drizzt的建议,替换一个分叉的亚壳+猫

$(</etc/passwd)

我有时使用的另一个选项是将IFS设置为XIFS,然后恢复。另参见Sorpigal的回答,它不需要为此费心

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

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

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

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


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

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

readarray -t a < /path/to/filename

一种替代方法,如果文件包含字符串没有空格,每行1string:

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


fileItemArray=($fileItemString)

检查:

打印整个数组:

${fileItemArray[*]}


Length=${#fileItemArray[@]}
#!/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

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

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