Bash:遍历文件的行,并将行分配给带编号的变量名



我打算读取一个短.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

有什么解决办法吗?

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技巧,请查看bash完成代码。

解决你的评论:如果你想处理行,因为他们进来,但仍然保存以前的行,我会用这个结构:

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

通过这种方式,您不必跳过任何语法圈来访问当前行(而不是必须声明对行$i的引用变量或其他东西)

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

eval line$i="$line"告诉bash计算字符串"line1=Line A",该字符串试图调用一个名为A的命令,并将环境变量"line1"设置为Line的值。你可能想输入eval "line$i='$line'"

最新更新