Cat, Less, Tail and Head

Table of Contents


cat

$ cat --version | head -n1
cat (GNU coreutils) 8.25

$ man cat
CAT(1)                           User Commands                          CAT(1)

NAME
       cat - concatenate files and print on the standard output

SYNOPSIS
       cat [OPTION]... [FILE]...

DESCRIPTION
       Concatenate FILE(s) to standard output.

       With no FILE, or when FILE is -, read standard input.
...
  • For below examples, marks_201* files contain 3 fields delimited by TAB
  • To avoid formatting issues, TAB has been converted to spaces using col -x while pasting the output here


Concatenate files

  • One or more files can be given as input and hence a lot of times, cat is used to quickly see contents of small single file on terminal
  • To save the output of concatenation, just redirect stdout
$ ls
marks_2015.txt  marks_2016.txt  marks_2017.txt

$ cat marks_201*
Name    Maths   Science
foo     67      78
bar     87      85
Name    Maths   Science
foo     70      75
bar     85      88
Name    Maths   Science
foo     68      76
bar     90      90

$ # save stdout to a file
$ cat marks_201* > all_marks.txt


Accepting input from stdin

$ # combining input from stdin and other files
$ printf 'Name\tMaths\tScience \nbaz\t56\t63\nbak\t71\t65\n' | cat - marks_2015.txt
Name    Maths   Science
baz     56      63
bak     71      65
Name    Maths   Science
foo     67      78
bar     87      85

$ # - can be placed in whatever order is required
$ printf 'Name\tMaths\tScience \nbaz\t56\t63\nbak\t71\t65\n' | cat marks_2015.txt -
Name    Maths   Science
foo     67      78
bar     87      85
Name    Maths   Science
baz     56      63
bak     71      65


Squeeze consecutive empty lines

$ printf 'hello\n\n\nworld\n\nhave a nice day\n'
hello


world

have a nice day
$ printf 'hello\n\n\nworld\n\nhave a nice day\n' | cat -s
hello

world

have a nice day


Prefix line numbers

$ # number all lines
$ cat -n marks_201*
     1  Name    Maths   Science
     2  foo     67      78
     3  bar     87      85
     4  Name    Maths   Science
     5  foo     70      75
     6  bar     85      88
     7  Name    Maths   Science
     8  foo     68      76
     9  bar     90      90

$ # number only non-empty lines
$ printf 'hello\n\n\nworld\n\nhave a nice day\n' | cat -sb
     1  hello

     2  world

     3  have a nice day
  • For more numbering options, check out the command nl
$ whatis nl
nl (1)               - number lines of files


Viewing special characters

  • End of line identified by $
  • Useful for example to see trailing spaces
$ cat -E marks_2015.txt
Name    Maths   Science $
foo     67      78$
bar     87      85$
  • TAB identified by ^I
$ cat -T marks_2015.txt
Name^IMaths^IScience 
foo^I67^I78
bar^I87^I85
$ # NUL character
$ printf 'foo\0bar\0baz\n' | cat -v
foo^@bar^@baz

$ # to check for dos-style line endings
$ printf 'Hello World!\r\n' | cat -v
Hello World!^M

$ printf 'Hello World!\r\n' | dos2unix | cat -v
Hello World!


Writing text to file

$ cat > sample.txt
This is an example of adding text to a new file using cat command.
Press Ctrl+d on a newline to save and quit.

$ cat sample.txt
This is an example of adding text to a new file using cat command.
Press Ctrl+d on a newline to save and quit.


tac

$ whatis tac
tac (1)              - concatenate and print files in reverse
$ tac --version | head -n1
tac (GNU coreutils) 8.25

$ seq 3 | tac
3
2
1

$ tac marks_2015.txt
bar     87      85
foo     67      78
Name    Maths   Science
  • Useful in cases where logic is easier to write when working on reversed file
  • Consider this made up log file, many Warning lines but need to extract only from last such Warning upto Error line
$ cat report.log
blah blah
Warning: something went wrong
more blah
whatever
Warning: something else went wrong
some text
some more text
Error: something seriously went wrong
blah blah blah

$ tac report.log | sed -n '/Error:/,/Warning:/p' | tac
Warning: something else went wrong
some text
some more text
Error: something seriously went wrong
  • Similarly, if characters in lines have to be reversed, use the rev command
$ whatis rev
rev (1)              - reverse lines characterwise


Useless use of cat

  • cat is used so frequently to view contents of a file that somehow users think other commands cannot handle file input
  • UUOC#Useless_use_of_cat)
  • Useless Use of Cat Award
$ cat report.log | grep -E 'Warning|Error'
Warning: something went wrong
Warning: something else went wrong
Error: something seriously went wrong
$ grep -E 'Warning|Error' report.log
Warning: something went wrong
Warning: something else went wrong
Error: something seriously went wrong
$ cat marks_2015.txt | tr 'A-Z' 'a-z'
name    maths   science
foo     67      78
bar     87      85
$ tr 'A-Z' 'a-z' < marks_2015.txt
name    maths   science
foo     67      78
bar     87      85
  • However, cat should definitely be used where concatenation is needed
$ grep -c 'foo' marks_201*
marks_2015.txt:1
marks_2016.txt:1
marks_2017.txt:1

$ # concatenation allows to get overall count in one-shot in this case
$ cat marks_201* | grep -c 'foo'
3


Further Reading for cat


less

$ less --version | head -n1
less 481 (GNU regular expressions)

$ # By default, pager is used to display the man pages
$ # and usually, pager is linked to less command
$ type pager less
pager is /usr/bin/pager
less is /usr/bin/less

$ realpath /usr/bin/pager
/bin/less
$ realpath /usr/bin/less
/bin/less
$ diff -s /usr/bin/pager /usr/bin/less
Files /usr/bin/pager and /usr/bin/less are identical
  • cat command is NOT suitable for viewing contents of large files on the Terminal
  • less displays contents of a file, automatically fits to size of Terminal, allows scrolling in either direction and other options for effective viewing
  • Usually, man command uses less command to display the help page
  • The navigation commands are similar to vi editor


Commonly used commands are given below, press h for summary of options

  • g go to start of file
  • G go to end of file
  • q quit
  • /pattern search for the given pattern in forward direction
  • ?pattern search for the given pattern in backward direction
  • n go to next pattern
  • N go to previous pattern


Further Reading for less


tail

$ tail --version | head -n1
tail (GNU coreutils) 8.25

$ man tail
TAIL(1)                          User Commands                         TAIL(1)

NAME
       tail - output the last part of files

SYNOPSIS
       tail [OPTION]... [FILE]...

DESCRIPTION
       Print  the  last  10  lines of each FILE to standard output.  With more
       than one FILE, precede each with a header giving the file name.

       With no FILE, or when FILE is -, read standard input.
...


linewise tail

Consider this sample file, with line numbers prefixed

$ cat sample.txt
 1) Hello World
 2) 
 3) Good day
 4) How are you
 5) 
 6) Just do-it
 7) Believe it
 8) 
 9) Today is sunny
10) Not a bit funny
11) No doubt you like it too
12) 
13) Much ado about nothing
14) He he he
15) Adios amigo
  • default behavior - display last 10 lines
$ tail sample.txt
 6) Just do-it
 7) Believe it
 8) 
 9) Today is sunny
10) Not a bit funny
11) No doubt you like it too
12) 
13) Much ado about nothing
14) He he he
15) Adios amigo
  • Use -n option to control number of lines to filter
$ tail -n3 sample.txt
13) Much ado about nothing
14) He he he
15) Adios amigo

$ # some versions of tail allow to skip explicit n character
$ tail -5 sample.txt
11) No doubt you like it too
12) 
13) Much ado about nothing
14) He he he
15) Adios amigo
  • when number is prefixed with + sign, all lines are fetched from that particular line number to end of file
$ tail -n +10 sample.txt
10) Not a bit funny
11) No doubt you like it too
12) 
13) Much ado about nothing
14) He he he
15) Adios amigo

$ seq 13 17 | tail -n +3
15
16
17


characterwise tail

  • Note that this works byte wise and not suitable for multi-byte character encodings
$ # last three characters including the newline character
$ echo 'Hi there!' | tail -c3
e!

$ # excluding the first character
$ echo 'Hi there!' | tail -c +2
i there!


multiple file input for tail

$ tail -n2 report.log sample.txt
==> report.log <==
Error: something seriously went wrong
blah blah blah

==> sample.txt <==
14) He he he
15) Adios amigo

$ # -q option to avoid filename in output
$ tail -q -n2 report.log sample.txt
Error: something seriously went wrong
blah blah blah
14) He he he
15) Adios amigo


Further Reading for tail


$ head --version | head -n1
head (GNU coreutils) 8.25

$ man head
HEAD(1)                          User Commands                         HEAD(1)

NAME
       head - output the first part of files

SYNOPSIS
       head [OPTION]... [FILE]...

DESCRIPTION
       Print  the  first  10 lines of each FILE to standard output.  With more
       than one FILE, precede each with a header giving the file name.

       With no FILE, or when FILE is -, read standard input.
...


linewise head

  • default behavior - display starting 10 lines
$ head sample.txt
 1) Hello World
 2) 
 3) Good day
 4) How are you
 5) 
 6) Just do-it
 7) Believe it
 8) 
 9) Today is sunny
10) Not a bit funny
  • Use -n option to control number of lines to filter
$ head -n3 sample.txt
 1) Hello World
 2) 
 3) Good day

$ # some versions of head allow to skip explicit n character
$ head -4 sample.txt
 1) Hello World
 2) 
 3) Good day
 4) How are you
  • when number is prefixed with - sign, all lines are fetched except those many lines to end of file
$ # except last 9 lines of file
$ head -n -9 sample.txt
 1) Hello World
 2) 
 3) Good day
 4) How are you
 5) 
 6) Just do-it

$ # except last 2 lines
$ seq 13 17 | head -n -2
13
14
15


characterwise head

  • Note that this works byte wise and not suitable for multi-byte character encodings
$ # if output of command doesn't end with newline, prompt will be on same line
$ # to highlight working of command, the prompt for such cases is not shown here

$ # first two characters
$ echo 'Hi there!' | head -c2
Hi

$ # excluding last four characters
$ echo 'Hi there!' | head -c -4
Hi the


multiple file input for head

$ head -n3 report.log sample.txt
==> report.log <==
blah blah
Warning: something went wrong
more blah

==> sample.txt <==
 1) Hello World
 2) 
 3) Good day

$ # -q option to avoid filename in output
$ head -q -n3 report.log sample.txt
blah blah
Warning: something went wrong
more blah
 1) Hello World
 2) 
 3) Good day


combining head and tail

  • Despite involving two commands, often this combination is faster than equivalent sed/awk versions
$ head -n11 sample.txt | tail -n3
 9) Today is sunny
10) Not a bit funny
11) No doubt you like it too

$ tail sample.txt | head -n2
 6) Just do-it
 7) Believe it


Further Reading for head


Text Editors

For editing text files, the following applications can be used. Of these, gedit, nano, vi and/or vim are available in most distros by default

Easy to use

Powerful text editors

Check out this analysis for some performance/feature comparisons of various text editors

results matching ""

    No results matching ""