Arrays “读取”选项卡将文件行分隔为数组

Arrays “读取”选项卡将文件行分隔为数组,arrays,bash,Arrays,Bash,我想逐行将文件读入脚本。文件中的每一行都是由一个选项卡分隔的多个值,我想将每一行读入一个数组 典型的bash“逐行读取文件”示例 在循环的每次迭代中,我希望每一行都进入一个数组,这样我就可以 while read line into myArray do echo myArray[0] echo myArray[1] echo myArray[2] done < "myfile" 然后在第二次迭代中,它会打印出来 value4 value5 value6 这可能吗?我能看到的唯一

我想逐行将文件读入脚本。文件中的每一行都是由一个选项卡分隔的多个值,我想将每一行读入一个数组

典型的bash“逐行读取文件”示例

在循环的每次迭代中,我希望每一行都进入一个数组,这样我就可以

while read line into myArray
do
 echo myArray[0]
 echo myArray[1]
 echo myArray[2]
done < "myfile"
然后在第二次迭代中,它会打印出来

value4
value5
value6
这可能吗?我能看到的唯一方法是编写一个小函数来手动分解这些值,bash中是否有对此的内置支持?

您非常接近:

while IFS=$'\t' read -r -a myArray
do
 echo "${myArray[0]}"
 echo "${myArray[1]}"
 echo "${myArray[2]}"
done < myfile
而IFS=$'\t'读取-r-a myArray
做
回显“${myArray[0]}”
回显“${myArray[1]}”
回显“${myArray[2]}”
完成

-r
告诉
read
在输入数据中并不特殊;
-a myArray
告诉它将输入行拆分为单词,并将结果存储在
myArray
中;
IFS=$'\t'
告诉它只使用制表符拆分单词,而不是常规的Bash默认值,也允许空格。)也可以拆分单词。请注意,这种方法会将一个或多个制表符视为分隔符,因此如果任何字段为空,则以后的字段将“移动”到数组中较早的位置。这样可以吗?)

如果确实要拆分每个单词(bash的意思)在每次while循环迭代中完全改变数组的不同数组索引中,@ruakh的答案是正确的。但是您可以使用read属性将每个读取的字拆分为不同的变量
column1
column2
column3
,就像在这个代码片段中一样

while IFS=$'\t' read -r column1 column2 column3 ; do
  printf "%b\n" "column1<${column1}>"
  printf "%b\n" "column2<${column2}>"
  printf "%b\n" "column3<${column3}>"
done < "myfile"
而IFS=$'\t'读取-r column1 column2 column3;do
printf“%b\n”列1
printf“%b\n”列2
printf“%b\n”列3
完成<“我的文件”
要获得类似的结果,请避免数组索引访问,并通过使用有意义的变量名来提高代码可读性(当然,使用
columnN
不是一个好主意)。

您也可以尝试

OIFS=$IFS;
IFS="\t";

animals=`cat animals.txt`
animalArray=$animals;

for animal in $animalArray
do
    echo $animal
done

IFS=$OIFS;

这是一个很好的答案,谢谢你这样分解它,我真的很感激。正是我需要的,谢谢:DNo,如果你删除
echo“${myArray[1]}”
echo“${myArray[2]}”
它仍然会给出相同的结果output@AhmedHussein:这是一个有趣的说法。这在OP的案例中显然是错误的--
echo
添加了一个换行符,OP很难混淆输出是否在正确的位置有换行符--但是如果您有类似但不同的情况,我邀请您发布您自己的问题,有足够的细节让别人来帮你。(如果你在这里评论并链接到你的问题,我会看一下。)我在geonames转储上尝试这个,有时有多个列是空的,这意味着多个选项卡被视为一个看到“移位”的选项卡正如您所描述的。我如何避免这种情况?@giorgio79:我能想到的最干净的方法是将整行读入一个变量(例如
IFS=read-r line
),然后使用
readarray
从本质上“拆分”将该变量放入数组:
readarray-d$'\t'-t myArray-r
由@gniourf\u gniourf添加避免反斜杠字符的扩展,如果这样做,
%b
可以在
printf
格式字符串中被
%s
替换,因为反斜杠替换字符将表示为文字使用与否取决于你真正想做什么。这似乎是对
cat
while IFS=$'\t' read -r -a myArray
do
 echo "${myArray[0]}"
 echo "${myArray[1]}"
 echo "${myArray[2]}"
done < myfile
while IFS=$'\t' read -r column1 column2 column3 ; do
  printf "%b\n" "column1<${column1}>"
  printf "%b\n" "column2<${column2}>"
  printf "%b\n" "column3<${column3}>"
done < "myfile"
OIFS=$IFS;
IFS="\t";

animals=`cat animals.txt`
animalArray=$animals;

for animal in $animalArray
do
    echo $animal
done

IFS=$OIFS;