libarchive«S bsdtarможе обробляти більшість з цих форматів файлів, так що ви можете зробити:
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
Що ви можете спростити (і вдосконалити, щоб відповідати регістру безвідмовно) з GNU за findдопомогою:
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
Це не друкує шлях до архіву, де ці *vacation*jpgфайли знаходяться. Щоб надрукувати це ім'я, ви можете замінити останній рядок на:
-exec sh -ac '
for ARCHIVE do
bsdtar tf "$ARCHIVE" "*vacation*jpg" |
awk '\''{print ENVIRON["ARCHIVE"] ": " $0}'\''
done' sh {} + 2> /dev/null
який дає вихід:
./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
Або з 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
}
Слід зазначити , що існує ряд інших форматів файлів, які тільки zipабо tgzфайли в маскуванні , як .jarі .docxфайли. Ви можете додати їх у свій шаблон пошуку find/ не важливо для розширення (як, наприклад, розширення не покладається на визначення типу файлу).zshbsdtar
Зауважте, що *vacation*.jpgвище узгоджується на повний шлях до архіву, а не лише ім'я файлу, тому воно буде відповідати, vacation.jpgале і далі vacation/2014/file.jpg.
Для того, щоб відповідати лише ім'ям файлу, одним із фокусів було б використання режиму вилучення , використання -s(підстановки), який використовує регулярні вирази з pпрапором для друку імен файлів, що співпадають, а потім переконайтесь, що жоден файл не вилучається, наприклад:
bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"
Зауважте, що він виводить список на stderr та додає >>до кожного рядка. У будь-якому випадку, bsdtarяк і більшість tarреалізацій, можна переплутати імена файлів, які відображаються на дисплеї, якщо вони містять символи, такі як нова лінія чи зворотна косою рисою (надається як \nабо \\).