Comment puis-je récursivement grep à travers des archives compressées?
16
J'essaie de savoir quels modules use Test::Versiondans cpan. J'ai donc l'habitude minicpande 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 me dit quel fichier dans l'archive et sur quelle ligne il se trouve.
(Remarque: ce ne sont pas toutes des tarballs, certains sont des fichiers zip)
Ok, appliquons la philosophie Unix. Quelles sont les composantes 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, comme find.
Archives: vous avez besoin d'un outil pour les lire.
La plupart des programmes Unix fonctionnent sur des fichiers. Donc, pour fonctionner facilement sur des composants d'archives, vous devez y accéder en tant que fichiers, en d'autres termes, 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.zipest accessible en tant que répertoire ~/.avfs/path/to/foo/zip#. AVFS fournit un accès en lecture seule aux formats de fichiers d'archives les plus courants.
~/.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 match de MOTIF. Le nom du fichier correspondant est dans $REPLY. La définition du replytableau transforme la correspondance en une liste de noms.
$REPLY\# est la vue du répertoire de l'archive.
$REPLY\#/**/*.pmcorrespond aux .pmfichiers de l'archive.
Le Nqualificatif glob transforme le modèle en liste vide s'il n'y a pas de correspondance.
cela crée l'autre problème intéressant de devoir monter puis démonter toutes les archives, car le problème est qu'il y a 22k archives qui doivent être recherchées
xenoterracide
@xenoterracide: En quoi est-ce un problème? Avec AVFS, vous avez un seul point de montage ( ~/.avfs), et l'accès à chaque archive est automatique ( ~/.avfs/path/to/archive.zip\#c'est un répertoire ordinaire sur le système de fichiers AVFS, pas un point de montage). Bien sûr, chaque archive à laquelle vous accédez signifie un peu de performances, mais c'est intrinsèque au problème.
Gilles 'SO- arrête d'être méchant'
@gilles seulement le fait que maintenant je dois passer au travers et comprendre comment les monter d'abord, ce qui semble un peu une mauvaise idée, mieux vaut les monter au fur et à mesure et démonter après avoir été fouillé.
xénoterracide
@xenoterracide: Encore une fois: non, vous n'avez pas besoin de les monter individuellement. Le flux de travail complet (à l'exception de l'installation d'AVFS si nécessaire) se trouve dans mes extraits de code.
Gilles 'SO- arrête d'être méchant'
@gilles bien je vais devoir creuser un peu ... parce que je reçois find: missing argument to -exec'` et beaucoup de ceci de zshzsh: Input/output error: Data-Maker-0.27
xenoterracide
0
Il semble que je puisse le faire de cette façon
find authors/ -type f -exec zgrep "Test::Version" '{}' +
#!/bin/bash
#
# tarballs to check in
find authors/ -type f | while read tarball; do
# get list of files in tarball (not dirs ending in /):
tar tzf $tarball | grep -v '/$' | while read file; do
# get contents of file and look for string
tar -Ozxf conform.tar.gz $file | grep -q 'Text::Version' && echo "Tar ($tarball) has matching File ($file)"
done
done
Je viens de voir votre exigence de numéro de ligne. Cela peut probablement fonctionner avec une combinaison de grep -n et awk pour capturer le numéro de ligne. Ne peut pas être aussi simple que grep -H pour lister le nom de fichier car il est toujours stdin, donc peut nécessiter plus de lignes.
Kyle Smith
erreurs tar (child): conform.tar.gz: Cannot open: No such file or directory tar (child): Error is not recoverable: exiting now tar: Child returned status 2 tar: Error is not recoverable: exiting now
survenues
aussi, je ne savais pas quand j'ai posté pour la première fois que certaines des archives sur cpan étaient des fichiers zip.
xenoterracide
Hm, j'ai testé avec une structure de fichiers .tar.gz uniquement - il pourrait être rendu plus robuste pour prendre des mesures appropriées en fonction du type de fichier, mais cela devrait donner un point de départ décent.
Kyle Smith
0
Peut-être que ma réponse sera utile pour quelqu'un:
#!/bin/bash
findpath=$(echo $1 | sed -r 's|(.*[^/]$)|\1/|')
# tarballs to check in
find $findpath -type f | while read tarball; do
# get list of files in tarball (not dirs ending in /):
if [ -n "$(file --mime-type $tarball | grep -e "application/jar")" ]; then
jar tf $tarball | grep -v '/$' | while read file; do
# get contents of file and look for string
grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")
if [ -n "$grepout" ]; then
echo "*** $tarball has matching file ($file):"
echo $grepout
fi
done
elif tar -tf $tarball 2>/dev/null; then
tar -tf $tarball | grep -v '/$' | while read file; do
# get contents of file and look for string
grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")
if [ -n "$grepout" ]; then
echo "*** $tarball has matching file ($file):"
echo $grepout
fi
done
else
file=""
grepout=$(grep $3 -e "$2" $tarball)
if [ -n "$grepout" ]; then
echo "*** $tarball has matching:"
echo $grepout
fi
fi
done
Après l'installation, p7zip-*vous pouvez faire ceci:
ls | xargs -I {} 7z l {} | grep whatever | less
Vous n'avez pas besoin d'utiliser lsavant le premier canal, quelle que soit la liste des fichiers compressés fonctionnera. La finale lessne montrera que le CHEMIN de la vie du listet à l'intérieur de l'archive compressée, mais pas le nom de celui-ci.
~/.avfs
), et l'accès à chaque archive est automatique (~/.avfs/path/to/archive.zip\#
c'est un répertoire ordinaire sur le système de fichiers AVFS, pas un point de montage). Bien sûr, chaque archive à laquelle vous accédez signifie un peu de performances, mais c'est intrinsèque au problème.find: missing argument to
-exec'` et beaucoup de ceci de zshzsh: Input/output error: Data-Maker-0.27
Il semble que je puisse le faire de cette façon
Cependant, cela donne des résultats comme:
ce qui n'est pas très spécifique à l'endroit où dans l'archive. J'espère que quelqu'un pourra trouver une meilleure réponse.
la source
Merci pour le défi, j'ai trouvé:
la source
tar (child): conform.tar.gz: Cannot open: No such file or directory tar (child): Error is not recoverable: exiting now tar: Child returned status 2 tar: Error is not recoverable: exiting now
Peut-être que ma réponse sera utile pour quelqu'un:
la source
Après l'installation,
p7zip-*
vous pouvez faire ceci:Vous n'avez pas besoin d'utiliser
ls
avant le premier canal, quelle que soit la liste des fichiers compressés fonctionnera. La finaleless
ne montrera que le CHEMIN de la vie du listet à l'intérieur de l'archive compressée, mais pas le nom de celui-ci.la source
Utilisez find pour localiser tous les fichiers nécessaires et zgrep pour rechercher les fichiers compressés:
Je n'ai pas testé cela sur des tarballs
la source