libarchive
è in bsdtar
grado di gestire la maggior parte di quei formati di file, quindi puoi fare:
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
Che puoi semplificare (e migliorare per far corrispondere maiuscole e minuscole) con GNU find
con:
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
Ciò non stampa il percorso dell'archivio in cui *vacation*jpg
si trovano quei file. Per stampare quel nome è possibile sostituire l'ultima riga con:
-exec sh -ac '
for ARCHIVE do
bsdtar tf "$ARCHIVE" "*vacation*jpg" |
awk '\''{print ENVIRON["ARCHIVE"] ": " $0}'\''
done' sh {} + 2> /dev/null
che fornisce un output come:
./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
O con 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
}
Nota che ci sono un certo numero di altri formati di file che sono giusti zip
o tgz
file sotto mentite spoglie .jar
o .docx
file. Puoi aggiungerli al tuo modello find
/ zsh
search, bsdtar
non importa l'estensione (come in, non si basa sull'estensione per determinare il tipo di file).
Si noti che *vacation*.jpg
sopra corrisponde al percorso completo del membro dell'archivio, non solo al nome del file, quindi corrisponderebbe a vacation.jpg
ma anche a vacation/2014/file.jpg
.
Per abbinare solo il nome del file, un trucco sarebbe usare la modalità di estrazione , usare -s
(sostituzione) che usa regexps con un p
flag per stampare i nomi dei file corrispondenti e quindi assicurarsi che nessun file sia estratto, come:
bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"
Notare che avrebbe generato l'elenco su stderr e aggiunto >>
a ogni riga. In ogni caso, bsdtar
come la maggior parte delle tar
implementazioni possono alterare i nomi dei file visualizzati se contengono alcuni caratteri come newline o barra rovesciata (renderizzati come \n
o \\
).