銀の弾丸

プログラミングに関して、いろいろ書き残していければと思っております。

ShellでZIPの特定ディレクトリ以下全ファイルをUnzip

CLIのunzipで、ZIPファイルから特定ディレクトリ以下の全ファイルを取り出す方法の覚書き。

f:id:takamints:20160612171903p:plain
photo credit: A Bag of Colors via photopin (license)

GUIのツールだと何も問題ありませんが、シェルから使うunzip(Info-Zipのunzip?)では、取り出すファイルを全て指定する必要があるようです。数によっては現実的にちょっと無理。ひとつふたつならOKですけどね。

「なんでオプション無いのかねえ・・・」と、しばらく途方に暮れていたのですが、以下のようにして解決しました。

$ unzip -d Foo Foo.zip `zipinfo -1 Foo.zip | grep '^Path\\/To\\/Target'` 
  1. バッククォート内で、zipinfoコマンドを使って、全ファイル名を標準出力へ出力。-1オプションでファイル名(だけ)の出力。
  2. 同じバッククォート内で、パイプで標準出力をgrepへ渡して、正規表現で特定のパス以下のファイル名だけに絞り込み。
  3. その出力を、コマンド置換で、unzipのコマンドラインに展開して抽出。ここでは-dオプションは出力先ディレクトリを指定しています。無くてもいいけど念のため。

何が有り難いってバッククォートでのコマンド置換(標準出力をコマンドラインへ展開)。 さらに今回初めて知ったのですが、$(command) でも同じことらしいですね。

知ってるつもりでも、調べてみると、さらに深い発見があったりして、いくつになってもお勉強ですな。


エクストラクター ポイズンリムーバー AP011
エクストラクター
売り上げランキング: 230
bashクックブック
bashクックブック
posted with amazlet at 16.06.12
Carl Albing JP Vossen Cameron Newham
オライリージャパン
売り上げランキング: 574,097

参考

unzipとzipinfoのヘルプ出力。

$ unzip -h
UnZip 6.00 of 20 April 2009, by Info-ZIP.  Maintained by C. Spieler.  Send
bug reports using http://www.info-zip.org/zip-bug.html; see README for details.

Usage: unzip [-Z] [-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]
  Default action is to extract files in list, except those in xlist, to exdir;
  file[.zip] may be a wildcard.  -Z => ZipInfo mode ("unzip -Z" for usage).

  -p  extract files to pipe, no messages     -l  list files (short format)
  -f  freshen existing files, create none    -t  test compressed archive data
  -u  update files, create if necessary      -z  display archive comment only
  -v  list verbosely/show version info       -T  timestamp archive to latest
  -x  exclude files that follow (in xlist)   -d  extract files into exdir
modifiers:
  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)
  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files
  -j  junk paths (do not make directories)   -aa treat ALL files as text
  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields
  -C  match filenames case-insensitively     -L  make (some) names lowercase
  -X  restore UID/GID info                   -V  retain VMS version numbers
  -K  keep setuid/setgid/tacky permissions   -M  pipe through "more" pager
See "unzip -hh" or unzip.txt for more help.  Examples:
  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip
  unzip -p foo | more  => send contents of foo.zip via pipe into program more
  unzip -fo foo ReadMe => quietly replace existing ReadMe if archive file newer
$ zipinfo -h
ZipInfo 3.00 of 20 April 2009, by Greg Roelofs and the Info-ZIP group.

List name, date/time, attribute, size, compression method, etc., about files
in list (excluding those in xlist) contained in the specified .zip archive(s).
"file[.zip]" may be a wildcard name containing *, ?, [] (e.g., "[a-j]*.zip").

   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]
      or:  unzip -Z [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]

main listing-format options:             -s  short Unix "ls -l" format (def.)
  -1  filenames ONLY, one per line       -m  medium Unix "ls -l" format
  -2  just filenames but allow -h/-t/-z  -l  long Unix "ls -l" format
                                         -v  verbose, multi-page format
miscellaneous options:
  -h  print header line       -t  print totals for listed files or for all
  -z  print zipfile comment   -T  print file times in sortable decimal format
  -C  be case-insensitive     -M  page output through built-in "more"
  -x  exclude filenames that follow from listing