libarchive„s bsdtarmoże obsługiwać większość z tych formatów, więc można zrobić:
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
Które możesz uprościć (i ulepszyć, aby dopasować bez rozróżniania wielkości liter) z GNU za findpomocą:
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
Nie powoduje to jednak wydrukowania ścieżki do archiwum, w którym znajdują się te *vacation*jpgpliki. Aby wydrukować tę nazwę, możesz zastąpić ostatni wiersz:
-exec sh -ac '
for ARCHIVE do
bsdtar tf "$ARCHIVE" "*vacation*jpg" |
awk '\''{print ENVIRON["ARCHIVE"] ": " $0}'\''
done' sh {} + 2> /dev/null
co daje wynik taki jak:
./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
Lub z 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
}
Należy pamiętać, że istnieje wiele innych formatów plików, które są po prostu ziplub tgzpliki w przebraniu, takie jak .jarlub .docxpliki. Możesz dodać je do wzorca find/ zshwyszukiwania, bsdtarnie przejmuje się rozszerzeniem (jak w, to nie zależy od rozszerzenia, aby określić typ pliku).
Zauważ, że *vacation*.jpgpowyższe jest dopasowane do pełnej ścieżki członka archiwum, nie tylko do nazwy pliku, więc pasowałoby do, vacation.jpgale także do vacation/2014/file.jpg.
Aby dopasować tylko nazwę pliku, jedną sztuczką byłoby użycie trybu wypakowania , użycie -s(podstawienie), które używa wyrażeń regularnych z pflagą do wydrukowania nazw pasujących plików, a następnie upewnienie się, że żaden plik nie jest wyodrębniony, na przykład:
bsdtar -'s|.*vacation[^/]*$||' -'s|.*||' -xf "$archive"
Zauważ, że wypisuje listę na stderr i dołącza >>do każdej linii. W każdym razie, bsdtarpodobnie jak większość tarimplementacji, może zmieniać nazwy wyświetlanych plików, jeśli zawierają one znaki takie jak znak nowej linii lub ukośnik odwrotny (renderowane jako \nlub \\).