To display the content of a file, we will use the cat
command. The cat
command displays the whole file content on stdout
. However, sometimes, we are interested in viewing only a few lines of a file. In this case, using cat
will be tedious because we will have to scroll down to particular lines that we are interested in.
Shell provides us the
head
and tail
commands to print only the lines in which we are interested in. The main difference between both the commands is, head
prints the lines from the beginning of the files, and tail prints the lines from the end of the files.
head [OPTION] [FILE …]
By default, head
prints first 10 lines of each FILE to stdout
. If no file is mentioned or '-
' is specified, the input is taken from stdin
.
The options available in head can be used to change how much of the content to be printed. The options available are described in the following table:
Let's see how many files /usr/lib64/
directory contains -
:
$ ls /usr/lib64 | wc 3954
We see that /usr/lib64
has 3954 files. Suppose, we don't want all the libraries names, but just the first five library names. We can use a head command for this as follows:
$ ls /usr/lib64 | head -n 5 akonadi alsa-lib ao apper apr-util-1
We use the -c
option to print the first few bytes of a file, as follows:
$ head -c50 /usr/share/dict/linux.words /usr/share/dict/words ==> /usr/share/dict/linux.words <== 1080 10-point 10th 11-point 12-point 16-point 18-p ==> /usr/share/dict/words <== 1080 10-point 10th 11-point 12-point 16-point 18-p
This first prints 50 bytes of the /usr/share/dict/linux.words
and /usr/share/dict/words
files.
We can eliminate the printing of the header having a filename using –q
:
$ head -c50 -q /usr/share/dict/linux.words /usr/share/dict/words 1080 10-point 10th 11-point 12-point 16-point 18-p1080 10-point 10th 11-point 12-point 16-point 18-p
For a single file, command head
doesn't print name of file in output. To see it, use –v
option:
$ head -c50 -v /usr/share/dict/linux.words ==> /usr/share/dict/linux.words <== 1080 10-point 10th 11-point 12-point 16-point 18-p
The syntax for tail
is as follows:
tail [OPTION] [FILE …]
By default, tail
prints the last 10 lines of each FILE
to stdout
. If no file is mentioned or '-
' is specified, the input is taken from stdin
.
The options available in tail
can be used to change how much of the content to be printed. The available options are described in the following table:
The tail
command is frequently used to check the error or message log for the last few run of commands. With each new run, logs are appended at the end of the line.
We will see in following example that kernel log entries are made when a new USB drive is added and when it is removed:
$ dmesg | tail -n7 # Log when USB was attached
[120060.536856] sd 10:0:0:0: Attached scsi generic sg1 type 0 [120060.540848] sd 10:0:0:0: [sdb] 1976320 512-byte logical blocks: (1.01 GB/965 MiB) [120060.541989] sd 10:0:0:0: [sdb] Write Protect is off [120060.541991] sd 10:0:0:0: [sdb] Mode Sense: 23 00 00 00 [120060.543125] sd 10:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA [120060.550464] sdb: sdb1 [120060.555682] sd 10:0:0:0: [sdb] Attached SCSI removable disk
$ dmesg | tail -n7 # USB unmounted
[120060.540848] sd 10:0:0:0: [sdb] 1976320 512-byte logical blocks: (1.01 GB/965 MiB) [120060.541989] sd 10:0:0:0: [sdb] Write Protect is off [120060.541991] sd 10:0:0:0: [sdb] Mode Sense: 23 00 00 00 [120060.543125] sd 10:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA [120060.550464] sdb: sdb1 [120060.555682] sd 10:0:0:0: [sdb] Attached SCSI removable disk [120110.466498] sdb: detected capacity change from 1011875840 to 0
We saw that when USB was unmounted, a new log entry was added:[120110.466498] sdb:
detected capacity change from 1011875840
to 0
To check the last 10 yum logs in an RPM-based system, we can do the following:
# sudo tail -n4 -v /var/log/yum.log
==> /var/log/yum.log-20150320 <== Mar 19 15:40:19 Updated: libgpg-error-1.17-2.fc21.i686 Mar 19 15:40:19 Updated: libgcrypt-1.6.3-1.fc21.i686 Mar 19 15:40:20 Updated: systemd-libs-216-21.fc21.i686 Mar 19 15:40:21 Updated: krb5-libs-1.12.2-14.fc21.i686
To see real-time logs, we can use the -f
option. For example, the /var/log/messages
file shows the general system activities. With tail -f
, appended log messages in /var/log/messages
will be printed on stdout
as well:
$ tail -f /var/log/messages
Jun 7 18:21:14 localhost dbus[667]: [system] Rejected send message, 10 matched rules; type="method_return", sender=":1.23" (uid=0 pid=1423 comm="/usr/lib/udisks2/udisksd --no-debug ") interface="(unset)" member="(unset)" error name="(unset)" requested_reply="0" destination=":1.355" (uid=1000 pid=25554 comm="kdeinit4: dolphin [kdeinit] --icon system-fil ") Jun 7 18:21:14 localhost systemd-udevd: error: /dev/sdb: No medium found Jun 7 18:21:14 localhost systemd-udevd: error: /dev/sdb: No medium found Jun 7 18:27:10 localhost kernel: [135288.809319] usb 3-1.2: USB disconnect, device number 14 Jun 7 18:27:10 localhost kernel: usb 3-1.2: USB disconnect, device number 14 Jun 7 18:27:10 localhost systemd-udevd: error opening USB device 'descriptors' file
The command prompt won't return back. Instead, the output will keep getting updated whenever there is new content in /var/log/messages
.
We can use head and tail to find any line of a file.
We will consider the /usr/share/dict/words
file as an example.
Now, to find the 10th line of this file, we can do the following:
$ head -10 /usr/share/dict/words | tail -n1 # 10th line 20-point $ head -200000 /usr/share/dict/words | tail -n1 # 200000th line intracartilaginous
18.224.73.77