Line anchors

We've already briefly mentioned line anchors. With the explanations we have presented up until now, we were only able to search for words in a line; we weren't yet able to set expectations on where those words were in the line. For this, we use line anchors.

In regular expressions, the ^ (caret) character signifies the beginning of a line, and a $ (dollar) represents the end of a line. We can use these within a search pattern, for example, in the following scenarios:

  • Look for the word error, but only at the beginning of a line: ^error
  • Look for lines ending in a dot: .$
  • Look for an empty line: ^$

The first usage, looking for something at the beginning of a line, should be pretty clear. The following example, which uses grep -i (remember, this allows us to search without case sensitivity), shows how we can use this to filter by line position:

reader@ubuntu:~/scripts/chapter_10$ grep -i 'regular' grep-file.txt 
We can use this regular file for testing grep.
Regular expressions are pretty cool
reader@ubuntu:~/scripts/chapter_10$ grep -i '^regular' grep-file.txt
Regular expressions are pretty cool

In the first search pattern, regular, we are returned two lines. This is not unexpected, since both lines contain the word regular (albeit with different casing).

Now, to just select the line that starts with the word Regular, we use the caret character ^ to form the pattern ^regular. This only returns the line where the word is in the first position on that line. (Note that if we did not choose to include -i on grep, we could have used [Rr]egular instead.)

The next example, where we look for lines ending in a dot, is a little bit more tricky. As you recall, the dot in regular expressions is considered a special character; it is a substitute for any other one character. If we use it normally, we will see all lines in the file return (since all lines end in any one character).

To actually search for a dot in the text, we need to escape the dot by prefixing it with a backslash; this tells the regular expression engine to not interpret the dot as a special character, but to search for it instead:

reader@ubuntu:~/scripts/chapter_10$ grep '.$' grep-file.txt 
We can use this regular file for testing grep.
Regular expressions are pretty cool
Did you ever realise that in the UK they say colour,
but in the USA they use color (and realize)!
Also, New Zealand is pretty far away.
reader@ubuntu:~/scripts/chapter_10$ grep '.$' grep-file.txt
We can use this regular file for testing grep.
Also, New Zealand is pretty far away.

Since the is used to escape special characters, you might encounter a situation where you are looking for a backslash in the text. In that case, you can use the backslash to escape the special functionality of the backslash! Your pattern will be \ in this case, which matches with the  strings.

In this example, we run into one other issue. So far, we have always quoted all patterns with single quotes. However, this isn't always needed! For example, grep cool grep-file.txt works just as well as grep 'cool' grep-file.txt.

So, why are we doing it? Hint: try the previous example, with the dot line endings, without quotes. Then remember that a dollar character in Bash is also used to denote variables. If we quote it, the $ will not be expanded on by Bash, which returns problematic results.

We will discuss Bash expansion in Chapter 16, Bash Parameter Substitution and Expansion.

Finally, we presented the ^$ pattern. This searches for a line beginning, followed directly by a line ending. There is only one situation where that occurs: an empty line.

To illustrate why you would want to find empty lines, let's look at a new grep flag: -v. This flag is shorthand for --invert-match, which should give a nice clue about what it actually does: instead of printing lines that match, it prints lines that do not match.

By using grep -v '^$' <file name>, you can print a file without empty lines. Give it a go on a random configuration file:

reader@ubuntu:/etc$ cat /etc/ssh/ssh_config 

# This is the ssh client system-wide configuration file. See
# ssh_config(5) for more information. This file provides defaults for
# users, and the values can be changed in per-user configuration files
# or on the command line.

# Configuration data is parsed as follows:
<SNIPPED>
reader@ubuntu:/etc$ grep -v '^$' /etc/ssh/ssh_config
# This is the ssh client system-wide configuration file. See
# ssh_config(5) for more information. This file provides defaults for
# users, and the values can be changed in per-user configuration files
# or on the command line.
# Configuration data is parsed as follows:
<SNIPPED>

As you can see, the /etc/ssh/ssh_config file starts with an empty line. Then, in between comment blocks, there is another empty line. By using grep -v '^$', these empty lines are removed. While this is a nice exercise, this does not really save us that many lines.

There is, however, one search pattern that is widely used and very powerful: filtering out comments from a configuration file. This operation gives us a quick overview of what is actually configured, and omits all comments (which have their own merit, but can be obstructive when you just want to see which options are configured).

To do this, we combine the beginning-of-line caret with a hashtag, which denotes a comment:

reader@ubuntu:/etc$ grep -v '^#' /etc/ssh/ssh_config 

Host *
SendEnv LANG LC_*
HashKnownHosts yes
GSSAPIAuthentication yes

This still prints all empty lines, but no longer prints the comments. In this particular file, out of the 51 lines, only four lines contain actual configuration directives! All other lines are either empty or contain comments. Pretty cool, right?

With grep, it is also possible to use multiple patterns at the same time. By using this, you can combine the filtering of empty lines and comment lines for a condensed, quick overview of configuration options. Multiple patterns are defined using the -e option. The full command in this case is grep -v -e '^$' -e '^#' /etc/ssh/ssh_config. Try it!
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.75.165