Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jan 2006 15:01:57 +0200
From:      Giorgos Keramidas <keramida@ceid.upatras.gr>
To:        Kristian Vaaf <vaaf@broadpark.no>, lars@gmx.at
Cc:        freebsd-questions@freebsd.org
Subject:   Re: My script to replace strings in ASCII files
Message-ID:  <20060112130157.GB1167@flame.pc>
In-Reply-To: <43C56D47.1040809@gmx.at>
References:  <f377343c7093.43c57793@broadpark.no> <43C56D47.1040809@gmx.at>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2006-01-11 21:40, lars <lars@gmx.at> wrote:
>Kristian Vaaf wrote:
>> Just curious, what do I need to do to be able to execute this
>> script like:
>>
>> $ text-replace old_string new_string
>>
>> I find it a bit inconvenient having to edit the script for
>> every thing I need to replace.

It is.  You should start using $1, $2, ... for options.

>> #!/usr/local/bin/bash
>> #
>> #   Replace old with new inside all text files.
>> #   $URBAN: text-replace.sh,v 1.0 2005/10/24 15:09:05 vaaf Exp $
>> #
>>
>> for file in `find . -type f ! -name ".*"`; do
>>
>> 	if [ "`file -b "$file" | grep text`" != "" ]; then
>>
>> 		sed -i '' "s/old/new/g" "$file"
>>
>> 		echo "$file: Done"
>>
>> 	fi
>>
>> done
>
> Why not open the file with vim and then
> :.,$s/old/new/

Heh, that's nice, and it may even work with multiple files using
vim's -c option in a way similar to sed(1):

    vim -c ':%s/old/new/' file

> Of course that's not scriptable...

Using the -c option shown above, it may be scriptable too :)

> Maybe you should interpolate the first and the second argument
> into your regexes in the substitution with sed,
> so you get "s/argument1/argument2/"
>
> Perl might help though.

This opens a whole can of worms though.  What if the user defined
command-line parameters contain special characters (i.e. single
quote, double quotes, etc.)?

Instead of having to go through all the hoops of parsing quotes
and other special characters in a shell script, and then invoking
sed on each file, passing one file at a time, I prefer using "in
place editing":

    $ grep emacs .bashrc
    export EDITOR='nemacs'
    alias emacs='nemacs'

    $ perl -pi -e "s/'nemacs'/'emacs'/g" .bashrc

    $ grep emacs .bashrc
    export EDITOR='emacs'
    alias emacs='emacs'

    $ perl -pi -e "s/'emacs'/'nemacs'/g" .bashrc

    $ grep emacs .bashrc
    export EDITOR='nemacs'
    alias emacs='nemacs'

    $

The number of files passed as 'extra' arguments to perl in this
case is only limited by the amount of text that can fit in a
single command-line, and if that's not enough you can use
xargs(1) to work around the limit:

    find . -type f -name \*foo\* | xargs perl -pi -e "s/old/new/g"

So, there's no need to write special shell scripts to do this :)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060112130157.GB1167>