将制表符分隔的文件行读入数组


69

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

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

while read line
do
echo $line;
done < "myfile"

但是对我来说,myfile看起来像这样(制表符分隔的值);

value1 value2 value3
value4 value5 value6

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

while read line into myArray
do
 echo myArray[0]
 echo myArray[1]
 echo myArray[2]
done < "myfile"

这将在第一次循环迭代中打印以下内容;

value1
value2
value3

然后在第二次迭代中它将打印

value4
value5
value6

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

Answers:


152

您非常接近:

while IFS=$'\t' read -r -a myArray
do
 echo "${myArray[0]}"
 echo "${myArray[1]}"
 echo "${myArray[2]}"
done < myfile

(该-r告诉read那个\是不是在输入数据的特殊;在-a myArray告诉它拆分输入行成文字并存储在结果myArray;以及IFS=$'\t'告诉它仅使用标签来分的话,不是也经常猛砸默认请注意,这种方法会将一个或多个制表符视为定界符,因此,如果任何字段为空白,则后面的字段将被“移动”到数组中的前面位置。可以吗?)


6
这是一个很好的答案,感谢您将其分解,我非常感谢。正是我需要的,谢谢:D
jwbensley

不,如果您将其删除echo "${myArray[1]}"echo "${myArray[2]}"它仍然会提供相同的输出
艾哈迈德·侯赛因

@AhmedHussein:这是一个有趣的说法。在OP的情况下显然是错误的-echo添加换行符,并且OP很难混淆输出是否在正确的位置放了换行符-但是如果您遇到类似但不同的情况,我邀请您发布自己的问题,要有足够的细节让别人帮助您。(如果您在这里评论并附带您的问题的链接,我会看一下。)
ruakh

11

如果您真的想将每个单词(bash含义)拆分为不同的数组索引,则在每次while循环迭代中完全更改数组,@ ruakh的答案就是正确的方法。但是你可以使用读取属性每读字拆分成不同的变量column1column2column3在此代码段像

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"

为了达到类似的结果,避免使用数组变量访问,并通过使用有意义的变量名来提高代码的可读性(当然columnN,这样做不是一个好主意)。


实际上-r加入由@gniourf_gniourf避免反斜线字符的扩展,如果这样做%b可以通过取代%sprintf格式字符串导致反斜杠scaped字符将被表示为文字。因此,是否使用它取决于您真正想要做什么。
slylittl3

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.