Solved

scripting find grep replace in shell

Posted on 2007-11-16
18
2,300 Views
Last Modified: 2013-12-27
Don't know if it matters, but using bash shell, I'm trying to do a find that will find all files with a patricular name that contains a particular text and do a vi substitute on that text.

Something like:

find . -name "MANIFEST.MF" -exec `vi - {} << EOD :%s/SOME_TEXT/NEW_TEXT/g :wq EOD` '{}' \;

The syntax probably isn't even remotely correct, but you get the gist of it. If you know of a better way, that's acceptible as well.
0
Comment
Question by:boucherc
  • 9
  • 4
  • 2
  • +3
18 Comments
 
LVL 3

Expert Comment

by:fseto
ID: 20303462
Instead of using vi, use sed...

find .  -name "MANIFEST.MF"  -exec sed  's/oldpatt/newpatt/g'  {} \;
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20303967
Hi,

Vi  is an interactive editor. You may use other line editors like ed or ex.

e.g.

ed file <END
1,$ s/old/new/g
w
q
END


0
 

Author Comment

by:boucherc
ID: 20304809
fseto's response finds them all, and looks to replace them, but after execution when I do a find -exec grep "oldpatt", it still exists in the files it supposedly changed.
0
 

Author Comment

by:boucherc
ID: 20304812
omarfarid, it needs to be a single line command.
0
 
LVL 84

Expert Comment

by:ozo
ID: 20305147
find .  -name "MANIFEST.MF"  -exec sed -i.bak 's/oldpatt/newpatt/g'  {} \;
0
 

Author Comment

by:boucherc
ID: 20306140
ozo, the above resulted in the following for each file that was attempted to be edited:

sed: illegal option -- i

Remember, this is Solaris 2.9, so some UNIX rules might not apply.
0
 
LVL 3

Expert Comment

by:fseto
ID: 20306177
Oops, forgot to pipe the output back to the orig file.  BTW, make sure you test this!  As if sed bombs, it will overwrite your existing data!  Instead of output to {}, you can use {}.new.  And then check for correctness.

find .  -name "MANIFEST.MF"  -exec sed  's/oldpatt/newpatt/g'  {} >! {} \;
0
 

Author Comment

by:boucherc
ID: 20306200
still didn't substitute them.
0
 

Author Comment

by:boucherc
ID: 20306210
it actually pipes it out to a file names !, which has the substituted text.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 6

Expert Comment

by:Talmash
ID: 20307524
do u have permissions to change the files?
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20307654
Hi,

boucherc:

Why don't you take my script and develop it furhter :)

Here a modified one:

Call it myscript:

export count=$#
while test $count -gt 0
do
ed $1 <END
1,$ s/old/new/g
w
q
END
shift
done

make the script executable:

chmod +x /path/to/myscript

Then use it with find

find . -name "MANIFEST.MF" -exec /path/to/myscript {} \;
0
 

Author Comment

by:boucherc
ID: 20307921
omar

I tried your version as a script and got the following:

count=1: is not an identifier

and to talmash, yes, I do have the permissions to change the file.
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20308167
Hi,

Which shell are you using? Can you till which line number gave the error?

Any way my script is incomplete. Please add the line below after END and before shift:

count=`expr $count - 1`

Also,

you may change export count=$# to

count=$#
export count
0
 

Author Comment

by:boucherc
ID: 20308419
I'm using bash, but wrote the script as bourne.
0
 

Author Comment

by:boucherc
ID: 20308549
after changing the export line to be 2 separate lines, I no longer get the "count=1: is not an identifier" error.

I named my script as change_manifest and here are its contents:

#!/bin/sh

count=$#
export count
while test $count -gt 0
do
ed $1 <END
1,$ s/jaleksyn/${LOGNAME}/g
w
q
END
shift
done

I didn't add the count=`expr $count - 1` line yet, but now I get the following when running
find . -name MANIFEST.MF -exec change_manifest {} \;

change_manifest: END: cannot open
change_manifest: 1,$: not found
 10:39am  up 25 day(s),  3:33,  2 users,  load average: 0.16, 0.17, 0.17
User     tty           login@  idle   JCPU   PCPU  what
root     console       2Nov0716days     23         -sh
dynamo   pts/1        10:20am                      w
change_manifest: q: not found
change_manifest: END: not found
change_manifest: END: cannot open
change_manifest: 1,$: not found
 10:39am  up 25 day(s),  3:33,  2 users,  load average: 0.16, 0.17, 0.17
User     tty           login@  idle   JCPU   PCPU  what
root     console       2Nov0716days     23         -sh
dynamo   pts/1        10:20am                      w
change_manifest: q: not found
change_manifest: END: not found
change_manifest: cannot shift


0
 
LVL 48

Accepted Solution

by:
Tintin earned 100 total points
ID: 20308870
If you really want a one liner, the following will work on Solaris.

for f in `find . -name MANIFEST.MF`;do sed s/SOME_TEXT/NEW_TEXT/ $f >$f.new && mv $f.new $f;done
0
 

Author Closing Comment

by:boucherc
ID: 31409711
BINGO! This was just what I was looking for.

Thank you.
0
 
LVL 40

Expert Comment

by:omarfarid
ID: 20309821
Hi,

Sorry boucherc

It seams my copy and paste did copy properly. It should have been << END

0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
Background Still having to process all these year-end "csv" files received from all these sources (including Government entities), sometimes we have the need to examine the contents due to data error, etc... As a "Unix" shop, our only readily …
Learn how to get help with Linux/Unix bash shell commands. Use help to read help documents for built in bash shell commands.: Use man to interface with the online reference manuals for shell commands.: Use man to search man pages for unknown command…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now