如何将文件的不同行读取到不同的变量?

如何将文件的不同行读取到不同的变量?

我想将文本文件的不同行读取到不同的变量。例如

input.txt

line1 foo foobar bar
line2 bar
line3 foo
line4 foobar bar

我希望这个结果存储在变量var1, var2,中var3,这样var4

var1=line1 foo foobar bar
var2=line2 bar

等等。

有人可以告诉我它是如何完成的吗?我尝试eval在 for 循环中使用。这似乎不起作用。

答案1

你会这样做:

unset -v line1 line2
{ IFS= read -r line1 && IFS= read -r line2; } < input.txt

或者:

{ line1=$(line) && line2=$(line); } < input.txt

(效率较低,因为line很少内置,并且大多数 shell 需要 fork 来实现命令替换。line也不再是标准命令)。

使用循环:

unset -v line1 line2 line3
for var in line1 line2 line3; do
  IFS= read -r "$var" || break
done < input.txt

或者自动将变量名称定义为line<++n>

n=1; while IFS= read -r "line$n"; do
  n=$((n + 1))
done < input.txt

请注意,bash支持数组变量和readarray将行读入数组的内置函数:

readarray -t line < input.txt

但请注意,与大多数其他 shell 相反,bash数组索引从 0 而不是 1 开始(继承自ksh),因此第一行将位于${line[0]},而不是${line[1]}(尽管正如@Costas 所示,你可以让readarray(又名mapfile)开始在索引 1 处写入值(bash数组也与大多数其他 shell 的情况相反)数组)与-O 1)。

也可以看看:理解“IFS=读取-r行”吗?

答案2

我建议使用数组来完成此类任务

mapfile -t -O 1 var <input.txt

所以你会得到每一行${var[1]}${var[2]}依此类推

答案3

严格来说这并不是您所要求的,但它可能适合您的需求。您可以使用 awk 序列化数据。请注意,如果您的 $1 不是有效的变量名称,这将会中断:

awk '
function quote(str,   d, m, x, y, z) {
  d = "\47"; m = split(str, x, d)
  for (y in x) z = z d x[y] (y < m ? d "\\" d : d)
  return z
}
{
  print $1 "=" quote($0)
}
' input.txt > /tmp/input.sh
. /tmp/input.sh

结果:

$ echo "$line1"
line1 foo foobar bar

相关内容