PDA

View Full Version : Is it possible to replace word in every file?


msetjadi
07-20-03, 10:29
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?

sathyaram_s
07-20-03, 14:50
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

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?

Damian Ibbotson
07-21-03, 07:27
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.

chillies
07-22-03, 18:14
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.


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?

Damian Ibbotson
07-23-03, 11:08
'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

sypher
07-23-03, 12:56
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.

chillies
07-23-03, 13:11
Thanks Damian ... I didn't know about the boundaries in sed and vi.

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!

msetjadi
08-08-03, 00:38
Yes it works. Thank You for all suggestion.


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.