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

根据BinaryZebra的评论的最新修订,并在这里testing 。 command eval允许将expression式保存在当前的执行环境中,而之前的expression式仅保持在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的build议来replace一个分叉的subshel​​l + cat

 $(</etc/passwd) 

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

readarray命令 (也拼写mapfile )是在bash 4中引入的,我相信。

 readarray a < /path/to/filename 

将文件的每一行读入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[@]}" 

如果文件包含不带空格的string(每行包含1个string)

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

检查:

打印整个arrays:

 ${fileItemArray[*]} Length=${#fileItemArray[@]} 

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

 file="somefileondisk" lines=`cat $file` for line in $lines; do echo "$line" done 
 #!/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