libarchive
의 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
또는로 렌더링 됨 \\
) 와 같은 문자가 포함되어 있으면 파일 이름이 표시 될 수 있습니다 .