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
/ не важливо для розширення (як, наприклад, розширення не покладається на визначення типу файлу).zsh
bsdtar
Зауважте, що *vacation*.jpg
вище узгоджується на повний шлях до архіву, а не лише ім'я файлу, тому воно буде відповідати, vacation.jpg
але і далі vacation/2014/file.jpg
.
Для того, щоб відповідати лише ім'ям файлу, одним із фокусів було б використання режиму вилучення , використання -s
(підстановки), який використовує регулярні вирази з p
прапором для друку імен файлів, що співпадають, а потім переконайтесь, що жоден файл не вилучається, наприклад:
bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"
Зауважте, що він виводить список на stderr та додає >>
до кожного рядка. У будь-якому випадку, bsdtar
як і більшість tar
реалізацій, можна переплутати імена файлів, які відображаються на дисплеї, якщо вони містять символи, такі як нова лінія чи зворотна косою рисою (надається як \n
або \\
).