Hello Tbach99k,
Based on what you describe
- common block of text on several lines
- many files with the same "extension"
- recursive search
I suggest a two part method.
Part 1:
To apply the same command on every file matching some pattern under a
directory. the best command is "find". From what you describe a
command like:
find . -name "*.html" -exec (command goes here) {} \; -print
will start in the current directory (.) and find all files with a name
ending with .html. Based on the options I listed, it will then execute
the command on each file and then print the filename (so you can
monitor progress).
Complete information on find should be available on your Unix (or
Linux) system under
man find
or
info find
Part 2:
To make a change like the one you describe, there are several
different methods you can use. A few follow:
[1] The programs diff and patch allow you to compare two files and
apply the change on one or more file in the same manner. The full
documentation of diff and patch are also available using man and info
commands. For example:
man diff
man patch
For your simple example, I wrote the original contents into a.txt, the
revised contents into b.txt (plus added a few extra lines above /
below) and then used
diff -u -2 a.txt b.txt > a.patch
which looks like this:
--- a.txt Sun Aug 22 19:16:37 2004
+++ b.txt Sun Aug 22 19:16:41 2004
@@ -4,8 +4,7 @@
code start
-foo
-foo
-fooo
+foo2
fooo
+foo
foo
code end
which is a code indicating the changes necessary to change a.txt into
b.txt. I used a "context" of two lines - requiring two lines to
preceed / follow the text to be replaced to match [in case the lines
move up / down the file].
Then after making some changes to a.txt and naming it c.txt, I was able to use
patch c.txt a.patch
to generate an updated c.txt file with the same changes as a.txt -> b.txt.
[2] The old command line editor "ed" can be commanded from a file.
Using your example, I created a simple shell script as follows:
#!/bin/sh
ed $1 <<EOF
/code start/,/code end/c
code start
foo2
fooo
foo
foo
code end
.
w
q
EOF
If named a.sh, run this using
sh a.sh (filename here)
and the script will change the lines starting with "code start" and
ending with "code end" with the lines up to the period. The last two
lines write the updated file / quit. You may also be able to use
ed -s $1
if your version of ed supports "silent" operation to suppress the size
of the file read / written. Note this is perhaps a little simpler to
set up than #1 since you type exactly what you want between the code
begin / code end in the script.
[3] The perl example suggested by ssl_answer (or using sed) handles
single line changes. The substitution can then be done in parts - with
sed even adding / deleting lines with the appropriate commands.
Depending on which option for part 2 you use, the command for changing
all your files will be something like:
find . -name "*.html" -exec patch {} (path to patch file) \;
or
find . -name "*.html" -exec sh a.sh {} \;
to process all the files.
Don't hesitate to ask for clarification if some part of the answer is
unclear or one of these commands does not work properly on your
system.
--Maniac |