Recherche d'une chaîne sur plusieurs fichiers zip

22

Je travaille sur SunOS 5.10. J'ai un dossier qui contient environ 200 fichiers zip. Chaque fichier zip contient un seul fichier texte. Je voudrais rechercher une chaîne spécifique dans tous les fichiers texte de tous les fichiers zip.

J'ai essayé ceci (qui recherche n'importe quel fichier texte dans le fichier zip contenant la chaîne "ORA-") mais cela n'a pas fonctionné.

zipgrep ORA-1680 *.zip

Quelle est la bonne chose à faire sans décompresser les fichiers zip?

ziggy
la source
Voir aussi Comment puis-je récursivement grep à travers des archives compressées? (pas un double exact, car les exigences y étaient plus compliquées).
Gilles 'SO- arrête d'être méchant'

Réponses:

26

Il n'est généralement pas possible de rechercher du contenu dans un fichier compressé sans le décompresser d'une manière ou d'une autre. Comme zipgrep n'est qu'un shellscript, enveloppant unzip et egrep lui-même, vous pourriez tout aussi bien le faire manuellement:

for file in *.zip; do unzip -c "$file" | grep "ORA-1680"; done

Si vous avez juste besoin de la liste des fichiers zip correspondants, vous pouvez utiliser quelque chose comme:

for file in *.zip; do
    if ( unzip -c "$file" | grep -q "ORA-1680"); then
        echo "$file"
    fi
done

De cette façon, vous décompressez uniquement vers la sortie standard (c'est-à-dire vers la mémoire) au lieu de décompresser les fichiers sur le disque. Vous pouvez bien sûr essayer de simplement grep -ales fichiers zip, mais selon le contenu du fichier et votre modèle, vous pouvez obtenir des faux positifs et / ou des faux négatifs.

Noé
la source
Où la première option décompresserait-elle les fichiers?
ziggy
2
unzip -cdécompresse le fichier vers stdout. Il n'écrit pas l'intégralité du fichier non compressé ailleurs.
Noah
+1 tks beaucoup ça me sauve la journée. J'ajoute juste echo "$ file"; décompressez -c "$ file" | grep -q "ORA-1680"; pour connaître le nom du fichier + le résultat.
Mike
2
Ma version des unzipusages -pdu streaming sur pipe!
gavenkoa
Cela fonctionne lorsque toutes les commandes sur une seule ligne ont renvoyé une "sortie standard", pas un nom de fichier +1
alimack
16

zipgrepprend un seul fichier. Pour le faire fonctionner sur plusieurs fichiers, mettez-le en boucle:

for i in *.zip
do
   zipgrep ORA-1680 "$i"
done
dogbane
la source
2
En une ligne qui for i in *.zip; do zipgrep TextToSearch $i && echo $i; done
affiche
4

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# . Il s'agit d'un système de fichiers FUSE , que vous pouvez installer sur Solaris. AVFS fournit un accès en lecture seule aux formats de fichiers d'archives les plus courants.

mountavfs
for z in ~/.avfs$PWD/*.zip; do
  find "$z#" -exec grep ORA-1680 {} +
done
fusermount -u ~/.avfs   # optional
Gilles 'SO- arrête d'être méchant'
la source