(Adapté de Comment puis-je récursivement grep à travers des archives compressées? )
Installez AVFS , un système de fichiers qui fournit un accès transparent à l'intérieur des archives. Exécutez d'abord cette commande une fois pour configurer une vue du système de fichiers de votre machine dans laquelle vous pouvez accéder aux archives comme s'il s'agissait de répertoires:
mountavfs
Après cela, si /path/to/archive.zip
est une archive reconnue, alors ~/.avfs/path/to/archive.zip#
est un répertoire qui semble contenir le contenu de l'archive.
find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*vacation*.jpg"
' {} 'Test::Version' \;
Explications:
- Montez le système de fichiers AVFS.
- Recherchez les fichiers d'archives dans
~/.avfs$PWD
, qui est la vue AVFS du répertoire actuel.
- Pour chaque archive, exécutez l'extrait de shell spécifié (avec
$0
= nom de l'archive et $1
= modèle à rechercher).
$0#
est la vue du répertoire de l'archive $0
.
{\}
plutôt que {}
nécessaire dans le cas où les find
substituts externes à l' {}
intérieur des -exec ;
arguments (certains le font, d'autres pas).
Ou en zsh ≥4.3:
mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)(e\''
reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')
Explications:
~/.avfs$PWD/**/*.(7z|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 reply
tableau transforme la correspondance en une liste de noms.
$REPLY\#
est la vue du répertoire de l'archive.
$REPLY\#/**/*vacation*.jpg
correspond aux *vacation*.jpg
fichiers de l'archive.
- Le
N
qualificatif glob transforme le modèle en liste vide s'il n'y a pas de correspondance.
Gilles 'SO- arrête d'être méchant'
la source
Ma solution habituelle :
Exemple:
Les résultats sont comme:
Si vous ne voulez que le fichier zip avec des hits dessus:
FILENAME ici est utilisé deux fois, vous pouvez donc utiliser une variable.
Avec find, vous pouvez utiliser PATH / TO / SEARCH
la source
Une autre solution qui fonctionne est
zgrep
la source
zgrep
s'agit-il? Cela ne fonctionne pas avec celui livré avec GNUgzip
(/bin/zgrep: -r: option not supported
,zgrep (gzip) 1.6
)La convivialité à mon humble avis devrait également être une chose en bash:
et pour le goudron (celui-ci n'a pas été testé ...)
la source
unzip
implémentation peut gérer les fichiers 7z ou tar.gz?libarchive
« sbsdtar
peut traiter la plupart de ces formats de fichiers, vous pouvez donc faire:Que vous pouvez simplifier (et améliorer pour correspondre à la casse) avec GNU
find
avec:Cela n'imprime pas le chemin de l'archive où
*vacation*jpg
se trouvent ces fichiers. Pour imprimer ce nom, vous pouvez remplacer la dernière ligne par:ce qui donne une sortie comme:
Ou avec
zsh
:Notez qu'il existe un certain nombre d'autres formats de fichiers qui sont juste
zip
ou destgz
fichiers déguisés comme.jar
ou des.docx
fichiers. Vous pouvez les ajouter à votre modèle de recherchefind
/zsh
,bsdtar
ne vous souciez pas de l'extension (comme dans, il ne dépend pas de l'extension pour déterminer le type du fichier).Notez que ce qui
*vacation*.jpg
précède est mis en correspondance sur le chemin d'accès complet aux membres de l'archive, pas seulement sur le nom du fichier, il correspondra donc survacation.jpg
mais aussi survacation/2014/file.jpg
.Pour faire correspondre le nom de fichier uniquement, une astuce consiste à utiliser le mode d' extraction , à utiliser
-s
(substitution) qui utilise des expressions rationnelles avec unp
indicateur pour imprimer les noms des fichiers correspondants, puis à vous assurer qu'aucun fichier n'est extrait, comme:Notez qu'il afficherait la liste sur stderr et l'ajouterait
>>
à chaque ligne. Dans tous les cas,bsdtar
comme la plupart destar
implémentations, les noms de fichiers affichés peuvent être modifiés s'ils contiennent des caractères tels que la nouvelle ligne ou la barre oblique inverse (rendue sous la forme\n
ou\\
).la source