zipアーカイブに複数のファイルが含まれている場合は、ディレクトリを作成します。

zipアーカイブに複数のファイルが含まれている場合は、ディレクトリを作成します。

アーカイブのルートディレクトリに複数のファイルが含まれている場合は、ファイル名を付けたディレクトリ(拡張子なし)を作成したいと思います。アーカイブにディレクトリが1つしか含まれていない場合は、簡単に抽出したいと思います。次のアーカイブがあるとしましょう。

# file: withdir.zip
somedir/alpha
somedir/beta
somedir/gamma

現在のディレクトリに解凍したら、簡単に抽出(unzip withdir.zip)したいと思います。

somedir/alpha
somedir/beta
somedir/gamma

今、次のアーカイブがあるとします。

# file: nodir.zip
alpha
beta
gamma

実行すると、unzip nodir.zip現在のディレクトリが3つのファイルに複雑になります。

alpha
beta
gamma

むしろ、以下を実行したいと思いますunzip -d nodir nodir.zip

nodir/alpha
nodir/beta
nodir/gamma

Nautilusを使用して「ここから抽出」を右クリックします。期待どおりに正確に動作します。しかし、残念ながら、同じ動作を生成するコマンドラインスイッチを見つけたりunzip作成したりできませんでした。7zこの目標を達成する方法は? GUIなしで他のツールを使用できますか?

答え1

私は次のようにします(zsh構文):

unz() (
  tmp=$(TMPDIR=. mktemp -d -- ${${argv[-1]:t:r}%.tar}.XXXXXX) || exit
  print -r >&2 "Extracting in $tmp"
  cd -- $tmp || exit
  [[ $argv[-1] = /* ]] || argv[-1]=../$argv[-1]
  (set -x; "$@"); ret=$?
  files=(*(ND[1,2]))
  case $#files in
    (0) print -r >&2 "No file created"
        rmdir -v "../$tmp";;
    (1) mv -v -- $files .. && rmdir -v ../$tmp;;
    (*) mv -vT ../$tmp ../$tmp:r;;
  esac && exit $ret
)

それは:

  1. とにかくディレクトリを作成してください
  2. コマンドの実行
  3. コマンドによって生成されたファイルの数によって異なります。
    • ディレクトリの削除(ファイルが作成されていない場合)
    • 1つのファイル/ディレクトリのみを作成する場合は、1レベル上に移動してディレクトリを削除します。
    • そうでない場合は、一時ディレクトリの末尾からランダムな文字列を削除してみてください。

このようにして、次のことができます。

unz unzip foo.zip
unz tar xf foo.tar.gz

extractコマンドの最後の引数が抽出するファイルであるとします。また、-vオプションがGNUツールを使用していると仮定します。 GNU以外のシステムでは、それを削除して手動で記録できます。mv -Tまた、GNUに固有のもので、mv名前を変更しようとするだけを強制します。

答え2

unzip両方とも指定されたディレクトリに出力するスイッチがあるため、7zアーカイブルートにファイル数を確認する簡単なスクリプトを作成し、必要に応じてスイッチを追加できます。

7z にスイッチがあり、-slt出力を機械がより容易に読むことができるのでより容易です。出力にはzipの各ファイルに1行が含まれていますPath = ...。ルートディレクトリのファイルには/値を含めないでください。

私はこのようにファイルを解凍する簡単なスクリプトを書いた。

#!/bin/sh
for archive in "$@"; do
    # count files in root dir
    rootfiles=$(7z l -slt "${archive}" | grep -c 'Path = [^/]*$')

    # add -o switch, if more than one file in root
    # checks for >2, because path of the zip file itself is listed too
    if [ $rootfiles -gt 2 ]; then
        filename=${archive##*/}
        rootname=${filename%.*}
        opt="-o${rootname}"
    fi

    #unpack
    7z x "${opt}" "${archive}"
done

編集:スクリプトはzipでも機能します。

答え3

パトロール隊員さまざまな種類のアーカイブを処理し、アーカイブに複数のファイルが含まれている場合は、サブディレクトリを作成して、抽出されたファイルが作業ディレクトリを複雑にするのを防ぎます。

プロフィールの作成

patool create archive.zip somedirectory

アーカイブ抽出

patool extract archive.zip

サポートされている形式のリストを取得するにはpatool formats

答え4

また、使用することができますウナル、複数のトップレベルファイルがある場合は、デフォルトでインクルードディレクトリを作成します。

$ touch 1 2
$ zip a.zip 1 2
  adding: 1 (stored 0%)
  adding: 2 (stored 0%)
$ unzip -l a.zip
Archive:  a.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  04-29-14 10:56   1
        0  04-29-14 10:56   2
 --------                   -------
        0                   2 files
$ unar a.zip
a.zip: Zip
  1  (0 B)... OK.
  2  (0 B)... OK.
Successfully extracted to "a".
$ ls a
1 2

-d常にインクルードディレクトリを作成するために追加されました。

関連情報