Viewing file contents in Linux
Four essential commands
Linux shell is text-based, there is no denying that. If you spend any amount of time there or sooner or yourself needing to find or replace a bunch of text in a bunch of files. To get you started, here’s a primer on the most common commands that will help you to get the will find job done.
cat
This little command was designed to concatenate several files by writing them to the standard output. However most of the time its used to display the contents of a single file.
$ cat numbers.txt
1
2
3
4
5
As it turns out, it’s a much more capable tool than that. A quick, look at the manual shows a variety of options, most of which control how lines should be displayed, for instance, the -n
option will show line numbers. Then we have an option used for squelching multiple blank lines, so if you’re dealing with unwanted empty lines, this will filter them out. Toke this file for example:
$ cat -n somelines.txt
1 line1
2
3
4 line2
When you add -s
on to of that, the output will become:
$ cat -ns somelines.txt
1 line1
2
3 line2
There are two more options that control how whitespace characters are displayed. There is -T
which will replace all tabulations with ^I
.The other one is -v
which will display all non-printable using the caret and M-
notation. Consider this simple example where we are printing the STX character (\002 in octal).
$ printf $"\002" | cat -
$ printf $"\002" | cat -A -
^B
There is also an option that marks the end of each line with a dollar character. It can be helpful when searching for trailing whitespace characters. The last three options are used to frequently together, that you actually have an alias for them. So instead of using -vTE
you can just type -A
, which saves you three keystrokes. Take a look at this file for example.
$ cat whitespace.txt
trailing
tab
$ cat -A whitespace.txt
trailing $
^Itab$
head
Another command for displaying text from multiple files. The difference between head
and cat
is that this one only displays thye first 10 lines. Of course this behaviour can be modified by using the -n
flag, so executing head -n 3
will display only the first three lines.
$ head -n 3 numbers.txt
1
2
3
But that’s not all! You can also use head
to omit a certain number of last lines. For instance, if you want to display every line but the last 3 you’d execute head -n -3
, for example:
$ head -n -3 numbers.txt
1
2
tail
A command similar to head
, but instead of displaying the first lines, it will display the last lines of a file. This one most often used when investigating log files — just view latest entries during some troubleshooting. What makes it truly useful is the option -f
or --follow
which will give you a live view of new lines as they are being added. Chances are you are already using tail in this fashion, if so you may find the --pid
option useful. It accepts a process number to monitor and tail
will follow the logfile as long as the corresponding process is alive.
Similarly to head
, there is also the -n
parameter to control the number of displayed lines, so running tail -n 2
will display, last two lines instead of the default 10. Yet again we are able to modify the behaviour of -n
, this time by adding a plus sign. So invoking tail -n +2
will display the whole life, starting from the second one.
$ tail -n 2 numbers.txt
4
5
$ tail -n +2 numbers.txt
2
3
4
5
grep
If you are looking for a specific pattern, but don’t fancy scrolling through hundreds of lines, then grep
has you want. The simplest use case would be to run grep <pattern> file
, which will find all lines containing said pattern, which can be a simple phrase or a regular expression (regex). It is also possible to find lines that do not match a pattern. All you need to do, is to use the -v
option. Bear in mind that most tools in Linux are case sensitive and grep
is no different, but you can force it to be case insensitive with -I
.
The default behaviour of grep
is to return the whole line in which the pattern occurs. But if you’re only interested in the matched part itself, using grep
with -o
will do just that. It’s usefulness isn’t immediately obvious when using a simple pattern, but with regex it’s an entirely different matter. When using a simple pattern, the -o
flag will always return the pattern itself. Take for example this simple example:
$ grep abc test.txt
abc
$ grep -E ab+c test.txt
abc
abbc
But what is a result without context? Thankfully, grep
is able to provide at least some. By using options -A
(or --after-context
) and -B
(or --before-context
)you are able to new some lines before and after your search result. To make it even better, feel free to add line numbers with the -n
flag.
$ grep -n -B 2 line2 somelines.txt
2-
3-
4:line2
If you feel its way too clunky, you may give -T
a try, which will add a nice tabulation. This is especially that useful when grepping several files, which you can do, since the filename will be visible in every line.
$ grep -nT ab somelines.txt whitespace.txt test.txt
whitespace.txt: 2: tab
test.txt: 1: abc
test.txt: 2: abbc
regex flavours
grep
supports a few variations of regular expressions and knowing the difference between them can save you a lot of time. Take for example this pattern questions?
. When using grep
in default mode, which is “Basic regex”, the question mark doesn’t have any special meaning. Here’s an example:
$ cat file.txt
A question ends with '?'
Example: Any questions?$ grep questions? file.txt
Example: Any questions?
But what will happen when we try the same pattern, but in “Extended mode”?
$ grep -E questions? file.txt
A question ends with '?'
Example: Any questions?
As you can see the difference is quite significant. Why is that? In Extended mode, the question mark will match the preceding item at most once. So in Basic mode our pattern matches exactly the expression, but in Extended mode it matches both question
and questions
since s
is optional. It can be easily verified:
$ grep -o questions? file.txt
questions?$ grep -Eo questions? file.txt
question
questions
less and more
Many times it is not enough to just use cat
. Sometimes you want to browse a file interactively, thankfully there are tools for that. Excluding various text editors, by far the most commonly used commands are less
and more
. They are great for browsing files, since they operate in read-only mode, which makes it impossible to introduce accidental changes. Out of these two, more
is the older one. You will find it on virtually any Linux distro, hoverer it is slower and not as feature-rich as less
, which comes with some pretty important advantages. One of them is the ability to move forward and backward through a file, as opposed more
where the only possible direction is down. You can scroll using arrows to go up and down. For faster navigation you can utilize PgUp
and PgDn
buttons or just jump to the end of a file with End
and back to the beginning with Home
. For more options see the docs.
With less
you are also able to search for a pattern in a file and jump between matches both forwards and backwards. Just open a file with less file.txt
. Then you can start the search prompt by pressing /
. Write your search string and hit Enter
. This will take you to the first occurrence, which will be highlighted. Then you can go to the next one by pressing n
and back back to the previous with N
. An alternative is to press ?
, which works just like /
but has an inverted search direction.
If you know what you are searching for, to it is possible to provide the pattern in advance: less --pattern=<pattern> file.txt
. Executing this command will open the file right at the first match.
When you’re done browsing, you can quit less
by pressing q
.
Conclusion
Those are some of the most used commands for viewing the contents of a file. I intentionally avoided any text editors and commands, like sed
, that might alter the contents.
Let me know if I missed your favourite command.