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
- Non-printing characters
- See Show Non-Printing Characters for more detailed info
$ # 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!
- the
-A
option is equivalent to-vET
- the
-e
option is equivalent to-vE
- If
dos2unix
andunix2dos
are not available, see How to convert DOS/Windows newline (CRLF) to Unix newline (\n)
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.
- See also how to use heredoc
- See also difference between Ctrl+c and Ctrl+d to signal end of stdin input in bash
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
- See GNU sed chapter for details on the
sed
command used below
- See GNU sed chapter for details on the
$ 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
- Use input redirection if a command doesn't accept file input
$ 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 Terminalless
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 usesless
command to display the help page - The navigation commands are similar to
vi
editor
Navigation commands
Commonly used commands are given below, press h
for summary of options
g
go to start of fileG
go to end of fileq
quit/pattern
search for the given pattern in forward direction?pattern
search for the given pattern in backward directionn
go to next patternN
go to previous pattern
Further Reading for less
- See
man less
for detailed info on commands and options. For example:-s
option to squeeze consecutive blank lines-N
option to prefix line number
less
command is an improved version ofmore
command- differences between most, more and less
- less Q&A on unix stackexchange
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
tail -f
and related options are beyond the scope of this tutorial. Below links might be useful- tail Q&A on unix stackexchange
- tail Q&A on stackoverflow
head
$ 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
- vim
- vim learning resources and vim reference for further info
- emacs
- atom
- sublime
Check out this analysis for some performance/feature comparisons of various text editors