Bash:遍历文件的行并为编号的变量名分配行

时间:2015-07-25 18:14:49

标签: bash eval

我打算读取一个简短的.txt文件的行,并将每一行分配给包含变量名中行号的变量。

文件example.txt如下所示:

Line A
Line B

当我运行以下代码时:

i=1
while read line; do
  eval line$i="$line"
  echo $line
  ((i=i+1))
done < example.txt

执行期间我期望的是:

Line A
Line B

然后可以打电话

$ echo $line1
Line A
$ echo $line2
Line B

但是,上面的代码会导致错误:

-bash: A: command not found

有关修复的想法吗?

2 个答案:

答案 0 :(得分:1)

引用删除与eval一起发生两次。在eval甚至运行之前,您的双引号将被删除。我甚至不会直接回答那个部分,因为有更好的方法可以做到这一点:

readarray line < example.txt  # bash 4
echo "${line[0]}"

或者,要完成您正在做的事情,每行使用不同的变量:

i=1
while read line$((i++)); do
    :
done < example.txt

另请查看printf -v varname "%s" value以获得更好/更安全的参考分配方式。

如果你想看一些复杂的参考调用bash shenanigans,请查看bash-completion代码。

解决你的评论:如果你想在他们进来时处理线路,但仍然保存以前的线路,我会选择这个结构:

lines=()
while read l;do
    lines+=( "$l" )
    echo "my line is $l"
done < "$infile"

通过这种方式,你不必跳过任何语法箍来访问当前行(相对于必须声明一个引用变量到行$ i或其他东西。)

Bash数组非常方便,因为您可以按值访问单个元素,或者可以"${#lines[@]}"来获取行数。请注意unset lines[4]留下空隙,而不是重新编号lines[5:infinity]。请参阅&#34;数组&#34; bash手册页中的部分。要查找记录$#扩展和其他内容的手册部分,请在手册中搜索##。参数扩展部分是bash 4.3手册页中的第一个命中。

答案 1 :(得分:1)

eval line$i="$line"告诉bash评估字符串“line1 = Line A”,该字符串尝试调用名为A的命令,并将环境变量“line1”设置为Line的值。您可能想要eval "line$i='$line'"