libarchive
« s bsdtar
peut 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 find
avec:
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*jpg
se 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 zip
ou des tgz
fichiers déguisés comme .jar
ou des .docx
fichiers. Vous pouvez les ajouter à votre modèle de recherche find
/ 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 sur vacation.jpg
mais 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 p
indicateur 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, bsdtar
comme la plupart des tar
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 \\
).