I would like to read different lines of a text file to different variables. For example

input.txt:

line1 foo foobar bar
line2 bar
line3 foo
line4 foobar bar

I want this result to be stored in variables var1, var2, var3 and var4 such that

var1=line1 foo foobar bar
var2=line2 bar

and so on.

Could someone please tell me how it is done. I tried to use eval in a for loop. It doesn't seem to work.

share|improve this question

You'd do:

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

Or:

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

(less efficient as line is rarely built-in and most shells need to fork to implement command substitution. line is also no longer a standard command).

To use a loop:

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

Or to automatically define the names of the variables as line<++n>:

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

Note that bash supports array variables and a readarray builtin to read lines into an array:

readarray -t line < input.txt

Note however that contrary to most other shells, bash array indices start at 0 not 1 (inherited from ksh), so the first line will be in ${line[0]}, not ${line[1]} (though as @Costas has shown, you can make readarray (aka mapfile) start writing the values at indice 1 (bash arrays also contrary to most other shells' being sparse arrays) with -O 1).

See also: Understand "IFS= read -r line"?

share|improve this answer
    
Thank you. This works. :) – neet 15 hours ago

I'd offer to use array for such task(s)

mapfile -t -O 1 var <input.txt

so you'll have each line in ${var[1]}, ${var[2]} and so on

share|improve this answer

This is not strictly what you asked for, but it might work for your needs. You can serialize the data with Awk. Note that this will break if your $1 is not a valid variable name:

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

Result:

$ echo "$line1"
line1 foo foobar bar
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.