将文件中的行读入 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
Read lines from a file into a Bash array
提问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 eval
allows 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 的建议,将分叉的 subshell+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 readarray
command(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 bash
array is this:
将文件的每一行读入bash
数组的最简单方法是:
IFS=$'\n' read -d '' -r -a lines < /etc/passwd
Now just index in to the array lines
to 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