Tux

...making Linux just a little more fun!

Talkback:133/cherian.html

[ In reference to "Easy Shell Scripting" in LG#133 ]

Papciak, Gerard (Gerry) [Gerard.Papciak at Encompassins.com]


Fri, 5 Jun 2009 21:37:41 -0500

Hello...

I have a number of files in a Unix directory that need certain words replaced.

For instance, for ever file inside /TEST I need the word 'whs' replaced with 'whs2'.

I have search and searched the sed command and kornshell scripting...no luck

Sed 's/whs/whs2/g /TEST*.* > outfile
The above came close but places the contents of all files into one.

Any advice?

-- Gerry Papciak Information Delivery

[[[Elided content]]]


Top    Back


Faber J. Fedor [faber at linuxnj.com]


Fri, 5 Jun 2009 23:37:31 -0400

On 05/06/09 21:37 -0500, Papciak, Gerard (Gerry) wrote:

> Hello...
> 
> I have a number of files in a Unix directory that need certain words
> replaced.
> 
> For instance, for ever file inside /TEST I need the word 'whs' replaced
> with 'whs2'.
> 
> I have search and searched the sed command and kornshell scripting...no
> luck
> 
> 
> Sed 's/whs/whs2/g /TEST*.* > outfile
> The above came close but places the contents of all files into one.
> 
> Any advice?

Try the following:

perl -p -i -e 's/whs/whs2/g' /TEST/*

(google 'perl pie' for details, or just wait for Ben to wake up :-)

-- 
 
Regards,
 
Faber Fedor
President
Linux New Jersey, Inc.
908-320-0357
800-706-0701


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Fri, 5 Jun 2009 23:30:49 -0500

On Fri, Jun 05, 2009 at 09:37:41PM -0500, Papciak, Gerard (Gerry) wrote:

> Hello
> 
> I have a number of files in a Unix directory that need certain words replaced.
> 
> For instance, for ever file inside /TEST I need the word 'whs' replaced with
> 'whs2'.
> 
> I have search and searched the sed command and kornshell scripting, no luck
> 
> 
> Sed s/whs/whs2/g /TEST*.* > outfile
> 
> The above came close but places the contents of all files into one.
> 
> Any advice?

You need the '-i' (in-place edit) option of 'sed':

sed -i 's/\<whs\>/&2/g' *

This will make the replacements within the individual files. Do note the use of '\<whs\>', which means '"whs" as a word' (that being what you asked for) and '&', which means 'string matched by previous regex'.

In the old days, before 'sed' stole that option from Perl :), the answer would have been a tiny bit more complex:

for file in *
do
	/usr/bin/sed 's/\<whs\>/&2/g' $file > $file.NEW
	/bin/mv $file.NEW $file
done
-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sat, 6 Jun 2009 00:52:59 -0500

[Gerry, please remember to include the list in the CC.]

On Fri, Jun 05, 2009 at 11:03:44PM -0500, Papciak, Gerard (Gerry) wrote:

> OK...you indicated sed -i 's/\<whs\>/&2/g' *  
> 
> 1st source of confusion:  \<whs\    ....I understand the backslashes can
> act as 'delimiters', but why the '<'-sign?
They're not delimiters; that would be the forward slashes. '\<word\>' is a construct used to define a stand-alone word rather than a string:

echo 'foobar'|sed 's/\<foo\>/xyz/'		# Still 'foobar'
echo 'foo bar'|sed 's/\<foo\>/xyz/'		# Now, it's 'xyz bar'
> SIMPLER CASE to HELP ME GET THIS...
> 
> fisw1pd2 /export/home/c3782/TEST> sed -i 's/rr/zz/g' *    
> sed: illegal option -- i

Whoops - you've got an older version of 'sed'.

ben@Jotunheim:~$ sed --version
GNU sed version 4.1.5

That's why I sent along the two different examples.

> I have 5 files in a directory: a.dat, b.dat, c.dat, d.dat, e.dat.
> 
> Each contains:  larry, gerry, diane, marianne, john, wally in separate
> lines.
> 
> I want to make each file look like this:  lazzy, gezzy, diane, marianne,
> john, wally.

I'll quote myself from my previous email:

> for file in *
> do
> 	/usr/bin/sed 's/\<whs\>/&2/g' $file > $file.NEW
> 	/bin/mv $file.NEW $file
> done

It would work the same way for the above case:

for file in *
do
	/usr/bin/sed 's/rr/zz/g' $file > $file.NEW
	/bin/mv $file.NEW $file
done

Or, as Faber mentioned, you could use Perl. It's had that '-i' option for a long time now.

perl -i~ -wpe 's/rr/zz/g' *

This will make your desired changes in all the files, saving the originals with a '~' extension. If you don't want the backups, then just leave off the '~'.

-- 
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *


Top    Back


Papciak, Gerard (Gerry) [Gerard.Papciak at Encompassins.com]


Thu, 11 Jun 2009 16:16:18 -0500

I learned today that I do not have perl scripting available on our Unix Box. We established that our version of 'sed' does not have all the features I need.

WE DO HAVE A WORKING SED COMMAND: sed 's/rr/qq/g' a.dat > out.dat

All that is left is the ability to create a cycling loop that routes all files within a directory through that sed-command. I have .ksh at my disposal. I want to update all files within a directory according to the command constructs...not just one file at a time. Got it?? :)

Thanks all.

-- 
Gerry Papciak
Information Delivery
office:  847-667-0535
cell:     847-363-7894


Top    Back


Thomas Adam [thomas.adam22 at gmail.com]


Thu, 11 Jun 2009 22:23:46 +0100

On Thu, 11 Jun 2009 16:16:18 -0500 "Papciak, Gerard (Gerry)" <Gerard.Papciak@Encompassins.com> wrote:

> I learned today that I do not have perl scripting available on our
> Unix Box.  We established that our version of 'sed' does not have all
> the features I need.
> 
> WE DO HAVE A WORKING SED COMMAND:   sed 's/rr/qq/g' a.dat > out.dat

You have an ancient installation of... something then.

So you have KSH? Great. What part of:

for i in *; do sed -e 's/rr/qq/g' "$i" > "$i.foo" && \
mv "$i.foo" "$i"; done

... is it which isn't going to work for you?

> All that is left is the ability to create a cycling loop that routes
> all files within a directory through that sed-command. I have .ksh at
> my disposal.  I want to update all files within a directory according
> to the command constructs...not just one file at a time.  Got it??  :)

"command constructs"? The only way you can do it file-by-file. Since you're going to have some ancient version of find, you can still do:

find /somewhere -type f -print | while read foo; do
#sed command here
done

But guess what? Other than recusiveness, that's no different to globbing -- so can you be more specific about why a for loop won't what you want?

Oh, and one more thing -- please don't top-post on this list, or any other.

-- Thomas Adam

-- 
"It was the cruelest game I've ever played and it's played inside my
head." -- "Hush The Warmth", Gorky's Zygotic Mynci.


Top    Back