Re: Rechercher une ligne dans un gros fichier trié
On Sun, Nov 14, 2004 at 07:42:38PM +0100, J.Pierre Pourrez wrote:
> Le script est executé une fois par semaine, le fichier de 14000 lignes
> est créé à chaque fois et correspond aux 14000 paquets de la Sarge.
Optimiser un script qui prend 5 minutes à s'executer toutes
les semaines n'est pas une bonne utilisation de son temps :)
Je vois au moins un changement à faire:
> # recenser tous les noms de fichiers des paquets dans Packages
> for PACKAGE in `find $DISTS_DIR -name Packages`; do
> grep $MOTIF $PACKAGE | sed "s!$MOTIF!$HOST/!" >> $TMPFILE
> done
> # on trie tous les noms de fichiers récupérés
> mv $TMPFILE $TMPFILE.orig
> cat $TMPFILE.orig | sort > $TMPFILE
> rm $TMPFILE.orig
Je remplacerai tout ça par:
cat `find $DISTS_DIR -name Packages` | grep $MOTIF | sed "s!$MOTIF!$HOST/!" | sort > $TMPFILE
(Ça marche les points d'exclamation? Mon shell n'a pas l'air
content avec ça...)
> # on supprime les paquets non recensés
> # éventuellement utiliser l'option -m de grep pour arrêter
> # la recherche à la première occurence
> for FICHIER in `find $HOST -name "*.deb"`; do
> if [ `grep -c $FICHIER $TMPFILE` = "0" ]; then
> echo "Remove $FICHIER"
> rm -f $FICHIER
> COUNT=$(($COUNT+1))
> fi
> done
Ok, c'est donc la partie dont tu parlais à l'origine. Je
n'ai pas d'idée évidente; une solution serait de construire
un script sed qui efface les lignes contenues dans $TMPFILE,
et l'appliquer à la sortie du find, donc qqch du genre:
sed -e "s/\//\\\\\//g" -e "s!\(.*\)!/\1/d!" $TMPFILE > $TMPFILE2
(pour se retrouver dans $TMPFILE2 avec des lignes du genre:
/\/var\/lib\/apt-proxy\/blahblah.deb/d
/\/var\/lib\/apt-proxy\/foobar.deb/d
...
Puis:
find $HOST -name "*.deb" | sed -f $TMPFILE2
(on peut alors retirer le `sort` de l'expression du haut, il
ne sert plus).
Selon l'implémentation de sed (et si sed arrive à gérer
14000 lignes de script...), ça peut être ou ne pas être
plus rapide que ta solution.
Y.
Reply to: