Sineatos
Sineatos

Reputation: 1017

How to output a text's first line and last line to the terminal as a single command

I have a text file named test.txt in current directory.now I want to output test.txt's first line and its last line to the terminal with cat text.txt | (head -1 ; tail -1), but the result is that it only outputs the first line to the terminal.

How do I output the first line and the last line using a single command?

Upvotes: 2

Views: 566

Answers (3)

mklement0
mklement0

Reputation: 437238

The problem with your command is that only the 1st command - head -1 - receives the stdin input, because it consumes it on reading, so that the 2nd command - tail -1 - receives no input.

In this particular case, you can use command grouping ({ ...; ...; }):

{ head -1; tail -1; } < text.txt 

Caveats:

  • The above only works with seekable input, meaning either a regular file, a here-string or here-doc.

    • It will not work with pipeline input (cat text.txt | { head -1; tail -1; }) or with input from a process substitutions ({ head -1; tail -1; } < <(cat text.txt)), because such input is not seekable (tail cannot scan from the end backward).
  • Even with seekable input this is not a generic method to send input to multiple commands at once.

    • The above only works because tail reads backwards from the end of the (seekable) input, irrespective of whether all the input has already been read or not.

As a simpler alternative that works generically, here's a sed solution:

sed -n '1p; $p' text.txt
  • -n suppresses output of lines by default
  • 1p matches line 1 and prints it (p).
  • $p matches the last line ($) and prints it.

Upvotes: 2

Gnubie
Gnubie

Reputation: 2607

Using tee:

cat text.txt | tee >(head -1) >(tail -1) > /dev/null

Upvotes: 0

Avinash Raj
Avinash Raj

Reputation: 174696

You could use awk.

awk 'NR==1{print}END{print}' file

Upvotes: 2

Related Questions