在bash中将文本分割成数组

时间:2013-08-06 13:06:01

标签: arrays bash ifs

我有一堆名为jtn216_<n>.o<m>的文件,其中nm是整数。第一个由我分配,第二个由系统分配。我需要检查每个文件的最后一行。我跑这把它分成数组

for i in {361..380}; do 
  v=$(tail -n 1 jtn216_$i.o*)
  IFS=' ' read -ra line <<< "$v"
  echo $line $v 
done
  

3499200 3499200 87650.5574975270 13.6931802555886
  1014400 1014400 87947.4382620423 13.9208064005841
  3475800 3475800 87779.1695691355 13.8939964916376
  3479200 3479200 87459.7284508034 13.7824644675699
  3827800 3827800 87868.7538056652 13.8792123626210
  2551600 2551600 87615.6417285010 13.8700006744178
  3818400 3818400 87872.1788028955 13.8942371285402
  3476800 3476800 87842.0543708163 13.9170342642747
  3481800 3481800 87670.5841054385 13.8808556469308
  2559200 2559200 87800.6530231416 13.8874423695824
  3841600 3841600 87804.3972028423 13.8657419719638
  916400 916400 87776.1342228681 13.8622746230494
  3839000 3839000 87662.8185016707 13.8576498806465
  3835200 3835200 87933.6917697832 14.0007327053153
  3482000 3482000 88323.3509854563 13.9453990979062
  3485400 3485400 87657.5078357100 13.8478805156354
  3484800 3484800 87757.3379321554 13.8215034461609
  3475400 3475400 87970.4729449120 13.9605031841208
  3481800 3481800 87612.4211302676 13.8327950845915
  2319400 2319400 87521.5669854330 13.8383953325475

我希望line是一个数组而不是v的第一个数值。我做错了什么?

4 个答案:

答案 0 :(得分:3)

我认为你只是错误地打印line。请改为echo "${line[@]}"

答案 1 :(得分:3)

你应该很好地解决数组变量$ line的内容,例如

echo "${line[0]}"
echo "${line[*]}"  # converts to a single string
echo "${line[@]}"  # converts to multiple elements i.e. multiple arguments for echo

当一个数组变量在没有索引的情况下被寻址时,它就等于获得第一个元素。

答案 2 :(得分:1)

如果您想将最后一行作为数组:

,请尝试以下操作
v=(`tail -n 1 jtn216_$i.o*`)

<强>已更新

要累积line作为数组使用:

v=(`tail -n 1 jtn216_$i.o*`)
line+=(${v[@]})

输出整个数组:

${line[@]}${line[*]}

计算数组元素的数量:

${#line[@]}${#line[*]}

答案 3 :(得分:1)

什么bash调用“数组”实际上只是一个单词列表(一个甚至不能嵌套的列表)。因此,如果您只是使用echo输出数组,那么您只需要它输出一个echo参数列表。考虑:

echo foo bar # 'foo bar\n'
echo -n foo bar # 'foo bar'
x=( -n foo bar )
echo "${x[@]}" # 'foo bar'

如果您输出的数组名称没有任何索引或@或*组件,您将获得该数组中的第一个单词*:

echo "$x" # foo

所以当你做echo $line $v时你真正说的是

echo ${line[0]} $v

这是你可能想要的:

for i in {361..380}; do 
  tail -n 1 jtn216_$i.o* | { # Pipe to a compound command to preserve assignments from read
    IFS=' ' read -ra line
    printf '[ '
    printf '%s ' "${line[@]}"
    printf ']\n'
  }
done

然后你应该看到

[ 3499200 87650.5574975270 13.6931802555886 ]
[ 1014400 87947.4382620423 13.9208064005841 ]
[ 3475800 87779.1695691355 13.8939964916376 ]
…

* Wordsplit 再次,因为你没有使用引号。