libarchive
„s bsdtar
moż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 find
pomocą:
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*jpg
pliki. 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 zip
lub tgz
pliki w przebraniu, takie jak .jar
lub .docx
pliki. Możesz dodać je do wzorca find
/ zsh
wyszukiwania, bsdtar
nie przejmuje się rozszerzeniem (jak w, to nie zależy od rozszerzenia, aby określić typ pliku).
Zauważ, że *vacation*.jpg
powyższe jest dopasowane do pełnej ścieżki członka archiwum, nie tylko do nazwy pliku, więc pasowałoby do, vacation.jpg
ale 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 p
flagą 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, bsdtar
podobnie jak większość tar
implementacji, może zmieniać nazwy wyświetlanych plików, jeśli zawierają one znaki takie jak znak nowej linii lub ukośnik odwrotny (renderowane jako \n
lub \\
).