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
またはとしてレンダリングされた\\
)などの文字が含まれている場合、ファイル名が表示される場合があります。