Solved

scripting find grep replace in shell

Posted on 2007-11-16
18
2,303 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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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
 
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 Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Remote install of MSI file 4 52
Retreiving column names in Windows but not in Unix 11 61
awk sed 8 70
how to include conditional log rotate in liunx. 17 41
FreeBSD on EC2 FreeBSD (https://www.freebsd.org) is a robust Unix-like operating system that has been around for many years. FreeBSD is available on Amazon EC2 through Amazon Machine Images (AMIs) provided by FreeBSD developer and security office…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
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…

820 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