If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Data Access, Manipulation & Batch Languages > Unix Shell Scripts > Is it possible to replace word in every file?

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 07-20-03, 09:29
msetjadi msetjadi is offline
Registered User
 
Join Date: Jun 2003
Posts: 35
Unhappy Is it possible to replace word in every file?

HI All,

I am very new in unix and i am not familiar if my requirements can be done in unix.

I need to replace a common word that exists inside thousands file,is impossible to edit one by one.

To all expert, are there any unix command that i can use to do this.
It might not be possible to do it once probably i need to creat a script but is it possible?

Do you know if there is a ready example?
Reply With Quote
  #2 (permalink)  
Old 07-20-03, 13:50
sathyaram_s sathyaram_s is offline
Super Moderator
 
Join Date: Aug 2001
Location: UK
Posts: 4,534
Re: Is it possible to replace word in every file?

for a single file i'll do

cat filename | sed 's/<current-word> <new-word> > filename.new
mv filename.new filename

A similar approach will work for multiple files also ...

There is likely to be a more efficient method to the same

Cheers
Sathyaram

Quote:
Originally posted by msetjadi
HI All,

I am very new in unix and i am not familiar if my requirements can be done in unix.

I need to replace a common word that exists inside thousands file,is impossible to edit one by one.

To all expert, are there any unix command that i can use to do this.
It might not be possible to do it once probably i need to creat a script but is it possible?

Do you know if there is a ready example?
__________________
Visit the new-look IDUG Website , register to gain access to the excellent content.
Reply With Quote
  #3 (permalink)  
Old 07-21-03, 06:27
Damian Ibbotson Damian Ibbotson is offline
Padawan
 
Join Date: Jun 2002
Location: UK
Posts: 525
I would do something like this for multiple files...

for fname in $(find . -name "*" -print)
do
sed '/word/s/word/new_word/g' ${fname} > ${fname}.new &&
mv ${fname}.new ${fname}
done


The 'find' command will output every filename that matches '*' (i.e. EVERY file) starting from the current directory ('.')

The 'for' loop will obviously cause the nested statements to occur for the list of substituted filenames.

The 'sed' command will substitute the word you require. Note: the initial occurrence of the word 'word' is not necessary but it makes the command more efficient as sed will only look to perform the substitution on lines that contain the match (as opposed to every line by default).

The use of '&&' is important because it means that the following command (i.e. 'mv') will only execute if the 'sed' command executed successfully.
Reply With Quote
  #4 (permalink)  
Old 07-22-03, 17:14
chillies chillies is offline
Registered User
 
Join Date: Jul 2003
Location: Edinburgh
Posts: 35
Re: Is it possible to replace word in every file?

The commands from the other two are very powerful, possibly too powerful. sed will textually replace any occurrence of a consecutive string of characters with the new ones, even if the old characters are part of a larger word e.g. 'the' is a substring of 'these' and sed s'/the/tea/' will output 'tease' rather than an unchanged 'the'.

perl is good for this: it has delimiters for word boundaries and the appropriate command is s/\bthe\b/tea/;

Before making the substitutions, it is worth testing the hypothesis that there are no substrings.


Quote:
Originally posted by msetjadi
HI All,

I am very new in unix and i am not familiar if my requirements can be done in unix.

I need to replace a common word that exists inside thousands file,is impossible to edit one by one.

To all expert, are there any unix command that i can use to do this.
It might not be possible to do it once probably i need to creat a script but is it possible?

Do you know if there is a ready example?
Reply With Quote
  #5 (permalink)  
Old 07-23-03, 10:08
Damian Ibbotson Damian Ibbotson is offline
Padawan
 
Join Date: Jun 2002
Location: UK
Posts: 525
'Chillies' is right - you need to be aware that sed is searching for patterns and has no implicit concept of words.

If you're lucky, your version of sed will support the word boundary chararcters \< and \>, so you could use...

sed 's/\<word\>/new_word/g' yourFile

If you're like me and your sed doesn't support this, you can write a more complex regex...

sed 's/\([^a-Z][^a-Z]*\)word\([^a-Z][^a-Z]*\)/\1new_word\2/g' < yourFile

(the above doesn't take into the 'word' being at the beginning of the line or the end of the line, so you'd have to string a few commands together to get exactly what you want!)

Alternatively, if you have vi (and I'm sure you do), vi should support the word boundary characters.

In a vi session type...

:%s/\<word\>/new_word/g
Reply With Quote
  #6 (permalink)  
Old 07-23-03, 11:56
sypher sypher is offline
Registered User
 
Join Date: Jan 2003
Location: Scotland
Posts: 17
Hi,

You could use this nice wee Perl command

perl -e 's/orig/new/gi' -p -i.bak *.log

The -i.bak will make a back up of all the original files,

I just put in *.log for an example you could use just * for everything

Just another way of doing it. Although I'd take heid of what the other 2 guys are saying

S.
Reply With Quote
  #7 (permalink)  
Old 07-23-03, 12:11
chillies chillies is offline
Registered User
 
Join Date: Jul 2003
Location: Edinburgh
Posts: 35
Thanks Damian ... I didn't know about the boundaries in sed and vi.

Quote:
Originally posted by Damian Ibbotson
(the above doesn't take into the 'word' being at the beginning of the line or the end of the line, so you'd have to string a few commands together to get exactly what you want!)
And possibly the string has hyphenation. It's a can of worms!
Reply With Quote
  #8 (permalink)  
Old 08-07-03, 23:38
msetjadi msetjadi is offline
Registered User
 
Join Date: Jun 2003
Posts: 35
Yes it works. Thank You for all suggestion.


Quote:
Originally posted by Damian Ibbotson
I would do something like this for multiple files...

for fname in $(find . -name "*" -print)
do
sed '/word/s/word/new_word/g' ${fname} > ${fname}.new &&
mv ${fname}.new ${fname}
done


The 'find' command will output every filename that matches '*' (i.e. EVERY file) starting from the current directory ('.')

The 'for' loop will obviously cause the nested statements to occur for the list of substituted filenames.

The 'sed' command will substitute the word you require. Note: the initial occurrence of the word 'word' is not necessary but it makes the command more efficient as sed will only look to perform the substitution on lines that contain the match (as opposed to every line by default).

The use of '&&' is important because it means that the following command (i.e. 'mv') will only execute if the 'sed' command executed successfully.
Reply With Quote
  #9 (permalink)  
Old 09-17-10, 17:18
biobee biobee is offline
Registered User
 
Join Date: Sep 2010
Posts: 1
Hello Damian,

I will be very obliged if you could help me with this query.I have used the code you have shared on this forum to replace one single word in all my files but I get an error. I am not sure why I am getting this error. Whether this is a ubuntu specific problem or a problem with my script.

Here is what I run:

Code:
#!/bin/bash
for fname in $(find . -name "*" -print)
do
sed '/word/s/rs#/rs/g' ${fname} > ${fname}.new &&
mv ${fname}.new ${fname}
done
Here is the error I get:
replace_word.sh: 3: Syntax error: word unexpected (expecting "do")

My environment is:
Linux version 2.6.32-24-server (buildd@yellow) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) )

Thanks
biobee


Quote:
Originally Posted by Damian Ibbotson View Post
I would do something like this for multiple files...

for fname in $(find . -name "*" -print)
do
sed '/word/s/word/new_word/g' ${fname} > ${fname}.new &&
mv ${fname}.new ${fname}
done


The 'find' command will output every filename that matches '*' (i.e. EVERY file) starting from the current directory ('.')

The 'for' loop will obviously cause the nested statements to occur for the list of substituted filenames.

The 'sed' command will substitute the word you require. Note: the initial occurrence of the word 'word' is not necessary but it makes the command more efficient as sed will only look to perform the substitution on lines that contain the match (as opposed to every line by default).

The use of '&&' is important because it means that the following command (i.e. 'mv') will only execute if the 'sed' command executed successfully.
Reply With Quote
  #10 (permalink)  
Old 09-18-10, 15:44
kitaman kitaman is offline
Papabi's friend
 
Join Date: Sep 2009
Location: Ontario
Posts: 626
Change your script to echo the file name (fname) for each occurrence. It is quite likely that one of the files has an embedded space, or carriage return in it.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On