libarchive« s bsdtarpeut traiter la plupart de ces formats de fichiers, vous pouvez donc faire:
find . \( -name '*.zip' -o \
-name '*.tar' -o \
-name '*.tar.gz' -o \
-name '*.tar.bz2' -o \
-name '*.tar.xz' -o \
-name '*.tgz' -o \
-name '*.tbz2' -o \
-name '*.7z' -o \
-name '*.iso' -o \
-name '*.cpio' -o \
-name '*.a' -o \
-name '*.ar' \) \
-type f \
-exec bsdtar tf {} '*vacation*jpg' \; 2> /dev/null
Que vous pouvez simplifier (et améliorer pour correspondre à la casse) avec GNU findavec:
find . -regextype egrep \
-iregex '.*\.(zip|7z|iso|cpio|ar?|tar(|\.[gx]z|\.bz2)|tgz|tbz2)' \
-type f \
-exec bsdtar tf {} '*vacation*jpg' \; 2> /dev/null
Cela n'imprime pas le chemin de l'archive où *vacation*jpgse trouvent ces fichiers. Pour imprimer ce nom, vous pouvez remplacer la dernière ligne par:
-exec sh -ac '
for ARCHIVE do
bsdtar tf "$ARCHIVE" "*vacation*jpg" |
awk '\''{print ENVIRON["ARCHIVE"] ": " $0}'\''
done' sh {} + 2> /dev/null
ce qui donne une sortie comme:
./a.zip: foo/blah_vacation.jpg
./a.zip: bar/blih_vacation.jpg
./a.tar.gz: foo/blah_vacation.jpg
./a.tar.gz: bar/blih_vacation.jpg
Ou avec zsh:
setopt extendedglob # best in ~/.zshrc
for archive (**/*.(#i)(zip|7z|iso|cpio|a|ar|tar(|.gz|.xz|.bz2)|tgz|tbz2)(.ND)) {
matches=("${(f@)$(bsdtar tf $archive '*vacation*jpg' 2> /dev/null)"})
(($#matches)) && printf '%s\n' "$archive: "$^matches
}
Notez qu'il existe un certain nombre d'autres formats de fichiers qui sont juste zipou des tgzfichiers déguisés comme .jarou des .docxfichiers. Vous pouvez les ajouter à votre modèle de recherche find/ zsh, bsdtarne 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*.jpgpré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 sur vacation.jpgmais aussi sur vacation/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 un pindicateur pour imprimer les noms des fichiers correspondants, puis à vous assurer qu'aucun fichier n'est extrait, comme:
bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"
Notez qu'il afficherait la liste sur stderr et l'ajouterait >>à chaque ligne. Dans tous les cas, bsdtarcomme la plupart des tarimplé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 \nou \\).