Avoiding shell for loops (was Re: Copying Multiple Files)

Gilles Courcoux gilles at chorus.fr
Wed Jun 13 21:59:02 AEST 1990


In article <3133 at goanna.cs.rmit.oz.au>, ok at goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
> 
> 	#!/bin/sh
> 	#   change "FromPattern" "ToPattern" File...
> 	#   see sed(1) for an explanation of patterns
> 	From="$1"
> 	shift
> 	To="$1"
> 	shift
> 	for File
> 	    do
> 		mv "$File" "`echo "$File" | sed -e "s/$From/$To/"`"
> 	    done
> 	exit

Just to say, there is one general improvement that can be used
on this type of code: don't use any loop at all!
Just build your commands with sed(1), then pipe them through the shell.

Doing so, you reduce the number of processes to fork (3 per file vs. 4),
and because `for' loops are very slow you get the whole job be
done faster.

      #!/bin/sh
      #   change "FromPattern" "ToPattern" File...
      #   see sed(1) for an explanation of patterns
      From="$1"
      shift
      To="$1"
      shift
      echo $* \
      | tr ' ' '\012' \
      | sed \
	-e "/$From/!d" \
	-e "s/$From/$To/" \
	-e 's/.*/mv & &/' \
	-e "s/$To/$From/" \
      | sh

The tr(1) command is just there to build an input stream of
one word per line for sed.

Note that you can say
	$ change .c .pouet *
because files not concerned by the move won't be moved (first line
of the sed script).

Gilles
--
Gilles Courcoux
Chorus systemes                          E-mail: gilles at chorus.fr
6 avenue Gustave Eiffel                  Phone: +33 (1) 30 57 00 22
F-78182, St-Quentin-en-Yvelines-Cedex    Fax: +33 (1) 30 57 00 66



More information about the Comp.unix.wizards mailing list