Table of contents
Special characters.
The characters typed onto the terminal can have special meanings. One of these is the *
which means to match any characters. These special characters can be challenging to write when executing commands on the terminal. e.g. the echo command prints its argument to the output. However, the special character *
will expand to all characters available in the directory which would print all names in the directory. What happens when the *
needs to be printed. The answer is using an escape sequence. This can be done by enclosing the *
in single quotes and as echo *
. The escape characters and special characters, usually used in wildcards, are important to the shell and this article lists them and their meanings.
Redirections.
One of the abilities of bash that makes it powerful is the ability to redirect the output and input of commands. While the commands typically output to the standard output (screen), this need not be the case. While they typically receive input from the standard input (keyboard), this need not be the case. The >
symbol will redirect output to a particular file overwriting any existing intent in that file. The >>
symbol will append the output of a command to a specified file. e.g. ls > tree.txt
or ls >> tree.txt
. To redirect input, the <
command is used. For example, sort < tree.txt
The commands can be used together so that: sort < tree.txt > sorted_tree.txt
.
Piping Commands
Piping is a form of redirection using the |
operator. This operator feeds the output of one command into another. In this example, the output of ls -al
is fed to the grep
command. ls -al | grep tree
. This ability gives the GNU/LINUX
system and bash a lot of power allowing a few lines of script to do a lot. You can read more on piping here. Let's look at some examples of applying these concepts.
Examples
Printing to the standard output (stdout)
echo "Hello, World"
To display a confused smiley
"(Ôo)'
In this case, the double quote has to be escaped when using the echo command. It then becomes
echo "\"(Ôo)'"
. The escape character\
tells bash to treat the"
as a normal character.To display the contents of a file, e.g.
/etc/passwd
The cat command is used:cat /etc/passwd
To display the contents of two files, use
cat
to display the contents of one then the other:cat /etc/passwd /etc/hosts
To display the last lines of a file, the
tail
command is used. To display a particular number of lines, use the-n
option with the tail. e.g. to display the last 10 lines of a file:tail -n 10 file
.The
head
command displays the first lines and works similarly to thetail
command.Using these commands, it is thus easy to display a particular line in a file. To display the fifth line, use the head command to get the first 5 then pipe it to the tail to get the last line of that output.
head -n 5 file | tail -n 1
.To create file named exactly \*\'"Best School"\'\*$\?\*\*\*\*\*:) containing the text Best School ending by a new line; simply redirect the output of echo into that file. Now the name of the file is tricky since it contains a lot of special characters and escape sequences. The single quotes make every single character inside them have a literal (non-special) meaning. However, to escape the single quote. One way to write the text is to put the parts before single quotes in single quotes, then print the single quote using double quotes
"'"
then repeat the process. Of course, there are other ways that you can try out as an exercise.#!/bin/bash echo "Best School" > '*\'"'"'"Best School"'"'"'\*$?*****:)'
To write a script that writes into the file
ls_cwd_content
the result of the command ls -la. If the filels_cwd_content
already exists, it should be overwritten. If the filels_cwd_content
does not exist, create it.ls -la > ls_cwd_content
.To delete all regular files(and only files, not directories) with a
.js
extension in the current folder and all its subfoldersfind . -type f -name '*.js' -delete
. Thefind
command searches in the directory hierarchy, the -type f specifies that only files should be gotten and the name gives the names with the -delete asking for them to be deleted.The
find
command can be used to manipulate the various files in a directory hierarchy and the output piped to other commands.man find
to learn all about its options. Write a script that counts the number of directories and sub-directories in the current directory. The current and parent directories should not be taken into account and hidden directories should be counted. Manipulate it asfind -mindepth 1 -type d | wc -l
The-mindepth
shows that the level from where the search starts can be changed.To display the newest files, use the
ls -t
option to organize them by modification time, then pipe it to the head or tail to find the latest (or earliest) files.To Create a script that takes a list of words as input and prints only words that appear exactly once, with;
Input format: One line, one word.
Output format: One line, one word.
Words should be sorted: pipe the output of sort to uniq:
sort | uniq -u
. The sorted output is fed to uniq. Runman uniq
to learn more about it.To find a single word from a given file use the
grep
command. To display lines containing the word root from/etc/passwd
simplygrep -E 'root' /etc/passwd
. In this case, grep searches for 'root' in'/etc/passwd'
. To count the number of lines that will be output, use the-c
option. To display a word and some lines after it, use the-A number
option.grep
with the-v
option hides the lines that contain a given word. e.g. to display lines that do not contain "root" in/etc/passwd
:grep -Ev 'root' /etc/passwd
.Grep also uses wildcards in its input in the shell.e.g. to display all lines starting with a letter:
egrep ^[[:alpha:]]
.The 'tr' command replaces a given letter(s) with others. e.g. To replace all characters
A
andc
from input toZ
ande
respectively:tr 'Ac' 'Ze'
. Runman tr
to learn more.When used with
-d
tr deletes given characters. e.g. To remove all lettersc
andC
from the input;tr -d Cc
.The
rev
command reverses its input.These commands are used such that they manipulate their inputs and feed their outputs to other commands. To display all users and their home directories, sorted by users in the
/etc/passwd
file:First, we'll need to remove sections from the file lines using the
cut
command. We'd then select our fields using the-f
option, and select our delimiters with the-d
option. The output of this is then fed to the sort command for our output. e.g.cut -f 1,6 -d ':' /etc/passwd | sort
.To find empty files within a given directory, the
find
command is used with the-empty
option. Therefore, to find all empty files and directories in the current directory and all sub-directories, printing their names followed by a new line and ending with a new line:find . -empty -printf "%f\n"
.These examples and commands would form good practice on redirections in the shell.