Differences between revisions 16 and 27 (spanning 11 versions)
Revision 16 as of 2011-02-13 08:02:47
Size: 1331
Editor: Lhunath
Comment:
Revision 27 as of 2012-02-27 02:27:07
Size: 1538
Editor: ormaaj
Comment: Agree with Lhunath - rm useless note. Fix writing style.
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:
The dirty (but not quick) way would be: One dirty (but not quick) way is:
Line 8: Line 8:
But this reads the entire file even if only the third line is desired, which can be avoided by printing line {{{$n}}} using the "p" command, followed by a "q" to exit the script:
Line 9: Line 10:
but this reads the whole input file, even if you only wanted the third line.

This one avoids that problem:
Line 15: Line 13:
Another method is to grab the last line from a listing of the first {{{n}}} lines:
Line 16: Line 15:
At line $n the command "p" is run, printing it, with a "q" afterwards: quit the program. {{{
   head -n $n $file | tail -n 1
}}}
Another approach, using [[AWK]]:
Line 18: Line 20:
Another way, more obvious to some, is to grab the last line from a listing of the first ''n'' lines:
{{{
   head -n $n $file | tail -n 1
}}}

Another approach, using [[AWK]]:
Line 27: Line 23:

If you want more than one line, it's pretty easy to adapt any of the previous methods:
If more than one line is needed, it's easy to adapt any of the previous methods:
Line 33: Line 28:
   head -n $y "$file" | tail -n $(($y - $x + 1)) # Same    head -n $y "$file" | tail -n $((y - x + 1))   # Same
Line 37: Line 32:
In Bash 4, a pure-bash solution can be achieved succinctly using the {{{mapfile}}} builtin. More than one line can be read into the array {{{MAPFILE}}} by adjusting the argument to mapfile's -n option:
Line 38: Line 34:
=== Note ===
In most cases, you should sanitize your variable n to be sure, that it's not containing any of non-digits, before feeding it to sed or awk. You can do it with such simple code:
Line 41: Line 35:
   # Bash
   n=${n//[!0-9]/}
   mapfile -ts $((n-1)) -n 1 < "$file"
   echo "${MAPFILE[0]}"
}}}
{{{mapfile}}} can also be used similarly to {{{head}}} while avoiding buffering issues in the event input is a pipe:
Line 44: Line 40:
   # POSIX
   n=$(printf "%s" "$n"|tr -cd '0-9')
{{{
   { mapfile -n $n; head -n 1; } <"$file"
Line 47: Line 43:

=== See Also ===
 * [[BashFAQ/001]]
 * http://wiki.bash-hackers.org/commands/builtin/mapfile

How can I print the n'th line of a file?

One dirty (but not quick) way is:

    sed -n ${n}p "$file"

But this reads the entire file even if only the third line is desired, which can be avoided by printing line $n using the "p" command, followed by a "q" to exit the script:

    sed -n "$n{p;q;}" "$file"

Another method is to grab the last line from a listing of the first n lines:

   head -n $n $file | tail -n 1

Another approach, using AWK:

   awk "NR==$n{print;exit}" file

If more than one line is needed, it's easy to adapt any of the previous methods:

   x=3 y=4
   sed -n "$x,${y}p;${y}q;" "$file"                # Print lines $x to $y; quit after $y.
   head -n $y "$file" | tail -n $((y - x + 1))     # Same
   head -n $y "$file" | tail -n +$x                # If your tail supports it
   awk "NR>=$x{print} NR==$y{exit}" "$file"        # Same

In Bash 4, a pure-bash solution can be achieved succinctly using the mapfile builtin. More than one line can be read into the array MAPFILE by adjusting the argument to mapfile's -n option:

   mapfile -ts $((n-1)) -n 1 < "$file"
   echo "${MAPFILE[0]}"

mapfile can also be used similarly to head while avoiding buffering issues in the event input is a pipe:

   { mapfile -n $n; head -n 1; } <"$file"

See Also


CategoryShell

BashFAQ/011 (last edited 2020-05-07 08:35:17 by intranet)