Google Answers Logo
View Question
 
Q: Global Replacie block of text in unix ( Answered,   1 Comment )
Question  
Subject: Global Replacie block of text in unix
Category: Computers > Programming
Asked by: tbach99k-ga
List Price: $5.00
Posted: 19 Aug 2004 22:35 PDT
Expires: 18 Sep 2004 22:35 PDT
Question ID: 390234
Looking for way to globally replace a block of text with another block
of text recuresively in a directory.

Clarification of Question by tbach99k-ga on 20 Aug 2004 10:00 PDT
I forgot i need a unix solution.

Request for Question Clarification by maniac-ga on 21 Aug 2004 10:44 PDT
Hello Tbach99k,

Please clarify:

Is this "block of text", on a single line or spread across multiple lines?
If so - I can suggest using sed or another similar tool to find / replace the text.

If on multiple lines, is the block of text formatted exactly the same
in each instance?
If so - the previous answer may also be applicable.

If no to both - this may require a program to be written.

  --Maniac

Clarification of Question by tbach99k-ga on 21 Aug 2004 11:57 PDT
Ok i meant to say a block of text like for instance if i had a google
adsense code and wanted to replace it with totally new code.
Also i meant if for instance i wanted to replace all files in
/home/needreplacing it would replace every single file in all
sub-dictiories to.
I found plenty of simple text replacements that will do a sentence or
so but i need say to replace

code start
foo
foo
fooo
fooo
foo
code end

with
code start
foo2
fooo
foo
foo
code end.
Like that on all files or all files with specific extention in a
directory and subdirectory.
Answer  
Subject: Re: Global Replacie block of text in unix
Answered By: maniac-ga on 22 Aug 2004 17:38 PDT
 
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
Comments  
Subject: Re: Global Replacie block of text in unix
From: ssl_answer-ga on 21 Aug 2004 15:02 PDT
 
You may try this:

find . -name "*.[ch]" -exec perl -pi.bak -e 's/Copyright (.*)
by/Copyright \(c\) 2004 by/g' {} \;

Sheng-Liang

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy