J'essaie de savoir quels modules use Test::Version
dans cpan. J'ai donc utilisé minicpan
pour le refléter. Mon problème est que je dois parcourir les archives téléchargées et grep les fichiers qui se trouvent dans les archives. Quelqu'un peut-il me dire comment je pourrais faire cela? de préférence d'une manière qui m'indique quel fichier dans l'archive et sur quelle ligne il se trouve.
(remarque :ce ne sont pas tous des fichiers tar, certains sont des fichiers zip)
Réponse acceptée :
Ok, appliquons la philosophie Unix. Quels sont les composants de cette tâche ?
- Recherche de texte :vous avez besoin d'un outil pour rechercher du texte dans un fichier, tel que
grep
. - Récursif :vous avez besoin d'un outil pour rechercher des fichiers dans une arborescence de répertoires, tel que
find
. - Archives :vous avez besoin d'un outil pour les lire.
La plupart des programmes Unix fonctionnent sur des fichiers. Ainsi, pour opérer facilement sur les composants de l'archive, vous devez y accéder en tant que fichiers, c'est-à-dire que vous devez y accéder en tant que répertoires.
Le système de fichiers AVFS présente une vue du système de fichiers où chaque fichier d'archive /path/to/foo.zip
est accessible en tant que répertoire ~/.avfs/path/to/foo/zip#
. AVFS fournit un accès en lecture seule aux formats de fichiers d'archive les plus courants.
mountavfs
find ~/.avfs"$PWD" ( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' )
-exec sh -c '
find "$0#" -name "*.pm" -exec grep "$1" {} +
' {} 'Test::Version' ;
fusermount -u ~/.avfs # optional
Explications :
- Montez le système de fichiers AVFS.
- Recherchez les fichiers d'archive dans
~/.avfs$PWD
, qui est la vue AVFS du répertoire courant. - Pour chaque archive, exécutez l'extrait de code shell spécifié (avec
$0
=nom de l'archive et$1
=modèle à rechercher). $0#
est la vue répertoire de l'archive$0
.{}
plutôt que{}
est nécessaire dans le cas où lefind
externe remplace{}
à l'intérieur de-exec ;
arguments (certains le font, d'autres non).- Facultatif :démontez enfin le système de fichiers AVFS.
Ou en zsh ≥4.3 :
mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e''
reply=($REPLY#/**/*.pm(.N))
'')
Explications :
~/.avfs$PWD/**/*.(tgz|tar.gz|zip)
correspond aux archives dans la vue AVFS du répertoire courant et de ses sous-répertoires.PATTERN(e''CODE'')
applique le CODE à chaque correspondance de PATTERN. Le nom du fichier correspondant est dans$REPLY
. Définition de lareply
array transforme la correspondance en une liste de noms.$REPLY#
est la vue répertoire de l'archive.$REPLY#/**/*.pm
correspond à.pm
fichiers dans l'archive.- Le
N
glob qualifier fait que le modèle se développe en une liste vide s'il n'y a pas de correspondance.