将文本行转换为数组

时间:2013-12-08 11:46:35

标签: bash

在我的bash脚本中,我有一个变量myvar,当echo'd打印多行时。

line1
line2
line3
line4
...

我想将这些行转换为数组并能够迭代它。

for i in "${myvar[@]}"
do
    echo "Line is: $i"
done

但这只是给出了:

Line is line1
line2
line3
line4
...

任何提示?

3 个答案:

答案 0 :(得分:1)

我不知道为什么你有一个带换行符的变量;也许你应该检查你的设计!

无论如何,在bash 4中,最干净,最有效的方法是使用mapfile

myvar=$'line1\nline2\nline3\nline 4 with spaces in it\nline 5 with no trailing newline'

mapfile -t myarray <<< "$myvar"

for i in "${myarray[@]}"; do
    echo "Line is: $i"
done

还有另一种可能性,摆弄IFS,但为此目的这太丑了。

请注意,与接受的答案(显示可怕的bash做法 - 你们肯定应该停止支持不良做法和破坏的代码)不同,这适用于空格。

现在,如果您的变量myvar实际上是从文件中获取的(因为您接受了显示此问题的答案,可能就是您的情况),直接获取文件file.txt的内容在一个数组中,其中的字段是文件的行,使用:

mapfile -t myarray < "file.txt"

for i in "${myarray[@]}"; do
    echo "Line is: $i"
done

它也会更有效率。

答案 1 :(得分:0)

我认为myvar只有一个字符串,以使myvar具有每行的数组。

#!/bin/bash

let -a myvar;

for line in `cat test.txt`
do
    myvar+=($line)
done

for i in "${myvar[@]}"
do
    echo "Line is: $i"
done

<强>输出

Line is: line1
Line is: line2
Line is: line3
Line is: line4

更新 - 性能测试

  • CentOS:6.4(在VirtualBox上运行)
  • bash:4.2.5
  • $ filename为40MB,包含120k行,每行约300字节。

  • Q1

    for line in `cat $filename`
    do
        myvar+=($line)
    done
    
  • Q2

    myvar=(`cat $filename`)
    
  • Q3

    mapfile -t myvar < "$filename"
    

<强>结果

  • Q1:28秒
  • Q2:11秒
  • Q3:&lt; 1秒。 (哇〜!)

答案 2 :(得分:0)

如果您的变量包含新行作为转义字符\n,那么您需要echo -e使其成为数组:

#!/usr/bin/env bash

myvar="Line1\nLine2\nLine3";
arr=$(echo -e $myvar)

for i in $arr
do
    echo $i
done