11

I am trying to print specific lines from a multi-line bash variable. I've found the following:

while read line; do echo LINE: "$line"; done <<< "$x"

where x would be the variable, but that simply prints out all lines instead of just a single one (say line 1 for instance). How could I go about adapting this to print out a specific line instead of all of them? (would like to avoid having to write the variable to a file instead)

lacrosse1991
  • 2,972
  • 7
  • 38
  • 47

3 Answers3

15

To print the Nth line:

sed -n ${N}p <<< "$x"

or (more portably):

sed -n ${N}p << EOF
$x
EOF

or

echo "$x" | sed -n "$N"p

or

echo "$x" | sed -n ${N}p

or (for the specific case N==3)

echo "$x" | sed -n 3p

or

while read line; do echo LINE: "$line"; done <<< "$x" | sed -n ${N}p

or

while read line; do echo LINE: "$line"; done << EOF | sed -n ${N}p
$x
EOF
William Pursell
  • 204,365
  • 48
  • 270
  • 300
11

You can split it into an array like:

IFS=$'\n' lines=($x)

Then you can access any line by indexing the array, e.g.:

echo ${lines[1]}

(of course, lines[0] is "line 1").

FatalError
  • 52,695
  • 14
  • 99
  • 116
2

If you don't want to use an array for some reason, and you want to do this within bash rather than by spawning an external tool like sed, you can simply count lines:

[ghoti@pc ~]$ x=$'one\ntwo\nthree\nfour\nfive\n'
[ghoti@pc ~]$ n=3
[ghoti@pc ~]$ for (( c=0; c<n; c++ )); do read line; done <<< "$x"
[ghoti@pc ~]$ echo $line
three
[ghoti@pc ~]$ 

Or using one fewer variable:

[ghoti@pc ~]$ n=2
[ghoti@pc ~]$ for (( ; n>0; n-- )); do read line; done <<< "$x"
[ghoti@pc ~]$ echo $line
two

These methods use what's sometimes called a "three expression for loop". It's a construct that's common in many languages, from bash to awk to perl to PHP to C (but not Python!). Getting to know them will help your programming in general.

Though ... you probably don't want to be using bash to learn "real" programming. :-)

ghoti
  • 45,319
  • 8
  • 65
  • 104