[gull] Script rechercher-remplacer
Claude Paroz
paroz at email.ch
Fri Jun 17 21:18:01 CEST 2005
Le vendredi 17 juin 2005 à 09:12 +0200, Daniel Cordey a écrit :
> On Thursday 16 June 2005 23:11, Claude Paroz wrote:
>
> > # loop for every line of the file
> > while [ `wc -l $f | cut -d" " -f1` -ge $i ]
>
> Maintenant que j'y regarde de plus pret... petits commentaires :
>
> - J'ecrirais plutot :
>
> while read line
> do
> ...
> done <$f
Intéressant, mais ça n'a pas l'air de marcher. Peut-être un conflit
entre les deux read ??
> - Une ecriture :
>
> 'wc -l $f | cut -d" " -f1`
>
> Peut-etre remplacee par :
>
> $(wc -l <$f)
>
> Remplacer les `` par $() n'a plus l'avantage de performance qu'il avait il y a
> longtemps mais c'est plus lisible (moins de chance de ne pas voir la
> difference entre `et '). Autrement, le fait d'utiliser '<' evite de se
> retrouver avec le nom du fichire que l'on elimine avec le 'cut'
Merci, j'en prends note.
> > # replace term and place newline in variable
> > newline=`printf "$newline\n" | sed -n
> > 's/'$1'/'$PATTERN'/1p'`
>
> - Pas besoin de preciser '-n', ni de '1p'. Un simple 'sed "s/$1/${PATTERN}/"
Effectivement, c'était un reste d'autres tests...
> Je prefere aussi utiliser les "" dans le cas ou je veux pouvoir 'evaluer' des
> variables a l'interieur. Cela evite les multiples ouvertures/fermetures de
> chaine de carcateres avec les ''. Aussi, j'ai pris l'habitude d'encapsuler
> les variable entre {}, afin de limiter les risques d'erreurs en delimitant
> clairement le nom d'une variable. Par exemple :
>
> X='toto'
> XX='titi'
>
> a="$XX"
>
> N'est peut-etre pas forcement ce que l'on veut, mais :
>
> a="${X}X"
> b="${XX}"
>
> n'est plus ambigu
>
> > # write the line in the new file
> > printf "$newline\n" >> $f.tmp
> > i=`expr $i + 1`
>
>
> printf est couteux ! (en temps...). Un simple
>
> echo "${newline" >> ${f}.tmp
>
> Aurait suffit.
Mon problème, c'est qu'avec echo, je perdais mes tabulateurs en début de
ligne, et fini l'indentation :-( C'est probablement par ce que j'avais
oublié de mettre la variable entre "". Maintenant, ça marche avec echo.
> Mais... le plus couteux dans l'affaire est le '>>'. En effet,
> comme cette commande se trouve dans uen boucle, le shell doit, a chaque
> boucle, ouvrir le fichier, deplacer le curseur a la fin puis refermer le
> fichier. Il est mieux d'encapsuler toute la boucle (exterieur !) dans :
>
> {
> for ...
> do
> ...
> echo "${newline}"
> done
> } > ${f}.tmp
Le problème, c'est qu'il y a d'autres "echo" dans la boucle dont le
résultat ne doit pas aboutir dans le fichier, mais seulement à l'écran.
>
> > mv $f.tmp $f
>
> Peut-etre serait-il judicieux de prendre l'habitude de tester si le fichier
> creer est non vide; ca peut-etre le signe d'un bug (le fait qu'il soit vide).
> Donc :
>
> test -s ${f}.tmp && mv ${f}.tmp ${f}
Effectivement, c'est une bonne idée.
Merci pour ces conseils. Je remets une nouvelle version, avec encore un
autre bug corrigé (remplacement du nième terme). Je n'ai pas
systématiquement ajouté les {} :
PATTERN="\<indexterm\>\<primary\>&\<\/primary\>\<\/indexterm\>"
FILESTOSCAN="en/*.xml"
for f in $(grep -il $1 $FILESTOSCAN)
do
echo "Find/Replace in file $f"
touch $f.tmp
i=1
# loop for every line of the file
while [ $(wc -l <$f) -ge $i ]
do
# read a line in the file
line=$(sed -n "${i}s/.*/&/p" $f)
newline=$line
j=1
while [ -n "$(echo $line | grep $1)" ]
do
echo -e "\n-------------------------------------------------\nLine
$i :"
echo $line | grep --colour=auto $1
echo -e "\nDo you want to index the first term '$1' in this line ?
[y-n]"
read answer
if [ "${answer}" == "y" ]
then
# replace term and place newline in variable
newline=$(echo "${newline}" | sed "s/$1/${PATTERN}/$j")
fi
# replace term with xxx in the line for catching second occurrence in
next loop
line=$(echo $line | sed "s/$1/xxx/")
j=$(expr $j + 1)
done
# write the line in the new file
echo "${newline}" >> $f.tmp
i=$(expr $i + 1)
done
# write new file over original one, if new file non empty
test -s $f.tmp && mv $f.tmp $f
done
Claude
Claude
More information about the gull
mailing list