You have a thousand C files in your directory (these end in '.c' by convention) and you need to correct a typo made in these files. You can solve this problem with a few simple lines of code.
Consider the simplest problem: making the changes in one file. You can do it by hand,
but this can only be automated at an extreme cost to yourself. We'll use the
command ed to do the job for us. The manual pages say
that ed is a line-oriented text editor: this means
it reads each line of a text file and performs a sequence of actions modifying the text. It then stores
the line in a buffer, and will only rewrite the file if the user requests the changes to the file are
saved. ed is unusual in that it accepts its commands
from standard input--which will be your keyboard if you type
ed file
you will recieve a blank line:
% ed is expecting input. Typing
q will move you out of
ed and back to the shell prompt. A typical session with
ed will look as follows:
% ed file
27
comand
comand
comand
w
q
25
The w tells ed
to save your changes back to the file. The number that is displayed before the first command
is the number of bytes in file, the last number is the number of bytes now in file
after it was edited. These are % ed's response to you.
You can learn about the commands
ed excepts from the
manual pages.
Do you see a problem with using ed? It has not saved
much time over manually opening-up each document. The Bash shell provides a nice facility that provides
the needed bridge: we can redirect standard input to read from Here (wherever that may be.) Here is an
example:
% ed file
<<TEXT
>comand
>comand
>comand
>w
>q
>TEXT
Notice that there is no response from ed
until the final TEXT is typed;
also there is now a prompt >
displayed. When you add <<TEXT
to the end of a command, Bash will wait for you to type some text, then direct
your text to standard input for the command; you inform Bash you are finished
by typing TEXT.
The redirection is cute, but so far it still requires you to be Here at the keyboard. The key though
is that you no longer need to be at the keyboard to feed commands to
ed: you could be anywhere. You can open-up a file
(lets call it myscript) and type:
ed file <<TEXT
comand
comand
comand
w
q
TEXT
To execute the contents of the file, you simple type on the command line
% bash myscript
and voilà, you have executed the commands to ed
from a file, not your keyboard. You now have your first shell script.
I have been steering you along, but we still do not seem to be any closer to solving our problem of editing
1000 files. Our "script" requires that we change the script for each file in our directory we want to
change. Then we must type a command on the prompt to execute this. Very true. Now, lets bring-out
the heavy cannonade: loops and variables. The Bash shell can be programed to automate
this process by adding a couple of lines to our script:
for file in *.c
do
ed $file <<TEXT
comand
comand
comand
w
q
TEXT
done
The first line of code tells Bash that for each of our files ending in ".c" in the current
directory, do the following routine, until you reach
done. In the Bash shell variables begin with
'$', as in $file. Now, when we type:
% bash myscript
Bash will make the changes to every one of our thousand files.
This last section is for simple aesthetics: we do not need to type
bash every time we want to run our script. Suppose
we want to re-use the script, do we really want to remember that we have to run it using
bash? You can use the following simple steps to convert
your bash or any other script such as a
gawk script to a simple command: