Viewing Part or Whole File Contents
In this chapter, you'll learn how to view contents of files from within the terminal. If the contents are too long, you can choose to view one screenful at a time or get only the starting/ending portions of the input. The commands used for these purposes also have other functionalities, some of which will be discussed in this chapter as well.
The example_files directory has the sample input files used in this chapter.
cat
The cat
command derives its name from concatenate. It is primarily used to combine the contents of multiple files to be saved in a file or sent as input to another command.
Commonly used options are shown below:
-n
prefix line number and a tab character to each input line-b
like-n
but doesn't number empty lines-s
squeeze consecutive empty lines to a single empty line-v
view special characters like NUL using the caret notation-e
view special characters as well as mark the end of line-A
includes-e
and also helps to spot tab characters
Here are some examples to showcase cat
's main utility. One or more files can be given as arguments.
As mentioned earlier, the example_files directory has the sample input files used in this chapter. You need to
cd
into theexample_files/text_files
directory to follow along the examples shown in this chapter.
# view contents of a single file
$ cat greeting.txt
Hi there
Have a nice day
# another example
$ cat fruits.txt
banana
papaya
mango
# concatenate multiple files
$ cat greeting.txt fruits.txt
Hi there
Have a nice day
banana
papaya
mango
To save the output of concatenation, use redirection:
$ cat greeting.txt fruits.txt > op.txt
$ cat op.txt
Hi there
Have a nice day
banana
papaya
mango
You can represent stdin
data using -
as a file argument. If file arguments are not present, cat
will read from stdin
data if present or wait for interactive input. Note that -
is also supported by many more commands to indicate stdin
data.
# concatenate contents of 'greeting.txt' and 'stdin' data
$ echo 'apple banana cherry' | cat greeting.txt -
Hi there
Have a nice day
apple banana cherry
Using
cat
to view the contents of a file, to concatenate them, etc is well and good. But, usingcat
when it is not needed is a bad habit that you should avoid. See wikipedia: UUOC and Useless Use of Cat Award for more details.
cat
also helps you spot special characters using the caret notation:
# example for backspace and carriage return characters
$ printf 'car\bd\nbike\rp\n'
cad
pike
$ printf 'car\bd\nbike\rp\n' | cat -v
car^Hd
bike^Mp
# example with tab characters and end-of-line marker
$ printf '1 2\t3\f4\v5 \n' | cat -A
1 2^I3^L4^K5 $
tac
You can concatenate files using tac
as well, but the output will be printed in the reverse (line wise). If you pass multiple input files, each file content will be reversed separately. Here are some examples:
$ printf 'apple\nbanana\ncherry\n' | tac
cherry
banana
apple
# won't be same as: cat greeting.txt fruits.txt | tac
$ tac greeting.txt fruits.txt
Have a nice day
Hi there
mango
papaya
banana
If the last line of input doesn't end with a newline, the output will also not have that newline character.
$ printf 'apple\nbanana\ncherry' | tac cherrybanana apple
less
The cat
command is not suitable for viewing contents of large files in the terminal. The less
command automatically fits the content to the size of the terminal, allows scrolling and has nifty features for effective viewing. Typically, the man
command uses less
as the pager
to display the documentation. The navigation options are similar to the Vim text editor.
Commonly used commands are given below. You can press the h
key for builtin help.
↑
and↓
arrow keys to move up and down by a line- you can also use
k
andj
keys (same keys as those used by the Vim text editor)
- you can also use
f
andb
keys to move forward and backward by a screenful of contentSpace
key also moves forward by a screen
- mouse scroll moves up and down by a few lines
g
orHome
go to the start of the fileG
orEnd
go to the end of the file/pattern
followed byEnter
search for the given pattern in the forward direction- pattern refers to regular expressions and depends on the regex library in your system
- the flavor is Extended Regular Expressions (ERE) on my system
- see
man re_format
for more details
?pattern
followed byEnter
search for the given pattern in the backward directionn
go to the next matchN
go to the previous matchq
quit
As an example, use less /usr/share/dict/words
to open a dictionary file and practice the commands discussed above. If your pager
is set to less
for manual pages, you can also try something like man ls
for practice.
Similar to the cat
command, you can use the -s
option to squeeze consecutive blank lines. But unlike cat -n
, you need to use less -N
to prefix line numbers. The lowercase -n
option will turn off numbering.
Further Reading
less
command is an improved version of themore
command- unix.stackexchange: differences between most, more and less
- My Vim Reference Guide ebook
tail
By default, tail
displays the last 10 lines of input files. If there are less than 10 lines in the input, only those lines will be displayed. You can use the -n
option to change the number of lines displayed. By using tail -n +N
, you can get all the lines starting from the N
th line.
Here's an example file that'll be used for illustration purposes:
$ cat sample.txt
1) Hello World
2)
3) Hi there
4) How are you
5)
6) Just do-it
7) Believe it
8)
9) banana
10) papaya
11) mango
12)
13) Much ado about nothing
14) He he he
15) Adios amigo
Here are some examples with the -n
option:
# last two lines (input has 15 lines)
$ tail -n2 sample.txt
14) He he he
15) Adios amigo
# all lines starting from the 11th line
# space between -n and +N is optional
$ tail -n +11 sample.txt
11) mango
12)
13) Much ado about nothing
14) He he he
15) Adios amigo
If you pass multiple input files, each file will be processed separately. By default, the output is nicely formatted with filename headers and empty line separators which you can override with the -q
(quiet) option.
$ tail -n2 fruits.txt sample.txt
==> fruits.txt <==
papaya
banana
==> sample.txt <==
14) He he he
15) Adios amigo
The -c
option works similar to the -n
option, but with bytes instead of lines:
# last three bytes
# note that the input doesn't end with a newline character
$ printf 'apple pie' | tail -c3
pie
# starting from the fifth byte
$ printf 'car\njeep\nbus\n' | tail -c +5
jeep
bus
Further Reading
- wikipedia: File monitoring with tail -f and -F options
- toolong — terminal application to view, tail, merge, and search log files
- unix.stackexchange: How does the tail -f option work?
- How to deal with output buffering?
head
By default, head
displays the first 10 lines of input files. If there are less than 10 lines in the input, only those lines will be displayed. You can use the -n
option to change the number of lines displayed. By using head -n -N
, you can get all the input lines except the last N
lines.
# first three lines
$ head -n3 sample.txt
1) Hello World
2)
3) Hi there
# except the last 11 lines
$ head -n -11 sample.txt
1) Hello World
2)
3) Hi there
4) How are you
You can select a range of lines by combining both the head
and tail
commands.
# 9th to 11th lines
# same as: tail -n +9 sample.txt | head -n3
$ head -n11 sample.txt | tail -n +9
9) banana
10) papaya
11) mango
If you pass multiple input files, each file will be processed separately. By default, the output is nicely formatted with filename headers and empty line separators which you can override with the -q
(quiet) option.
$ printf '1\n2\n' | head -n1 greeting.txt -
==> greeting.txt <==
Hi there
==> standard input <==
1
The -c
option works similar to the -n
option, but with bytes instead of lines:
# first three bytes
$ printf 'apple pie' | head -c3
app
# excluding the last four bytes
$ printf 'car\njeep\nbus\n' | head -c -4
car
jeep
Exercises
Use the example_files/text_files directory for input files used in the following exercises.
1) Which option(s) would you use to get the output shown below?
$ printf '\n\n\ndragon\n\n\nunicorn\n\n\n' | cat # ???
1 dragon
2 unicorn
2) Pass appropriate arguments to the cat
command to get the output shown below.
$ cat greeting.txt
Hi there
Have a nice day
$ echo '42 apples and 100 bananas' | cat # ???
42 apples and 100 bananas
Hi there
Have a nice day
3) Will the two commands shown below produce the same output? If not, why not?
$ cat fruits.txt ip.txt | tac
$ tac fruits.txt ip.txt
4) Go through the manual for the tac
command and use appropriate options and arguments to get the output shown below.
$ cat blocks.txt
%=%=
apple
banana
%=%=
brown
green
# ???
%=%=
brown
green
%=%=
apple
banana
5) What is the difference between less -n
and less -N
options? Does cat -n
and less -n
have similar functionality?
6) Which command would you use to open another file from within an existing less
session? And which commands would you use to navigate between previous and next files?
7) Use appropriate commands and shell features to get the output shown below.
$ printf 'carpet\njeep\nbus\n'
carpet
jeep
bus
# use the above 'printf' command for input data
$ c=# ???
$ echo "$c"
car
8) How would you display all the input lines except the first one?
$ printf 'apple\nfig\ncarpet\njeep\nbus\n' | # ???
fig
carpet
jeep
bus
9) Which command(s) would you use to get the output shown below?
$ cat fruits.txt
banana
papaya
mango
$ cat blocks.txt
%=%=
apple
banana
%=%=
brown
green
# ???
banana
papaya
%=%=
apple
10) Use a combination of the head
and tail
commands to get the 11th to 14th characters from the given input.
$ printf 'apple\nfig\ncarpet\njeep\nbus\n' | # ???
carp
11) Extract the starting six bytes from the input files table.txt
and fruits.txt
.
# ???
brown banana
12) Extract the last six bytes from the input files fruits.txt
and table.txt
.
# ???
mango
3.14