回答:
Mathiasが言ったように、そのunzip
ようなオプションはありませんが、1行のbashスクリプトで仕事をすることができます。
問題は、最適なアプローチがアーカイブレイアウトに依存することです。単一の最上位ディレクトリを想定するソリューションは、コンテンツが直接アーカイブルートにある場合、惨めに失敗します(/a/foo
/b/foo
/foo
ストリッピング/a
との混乱を考えてください/b
)。
そして、同じ失敗がで起こりtar --strip-component
ます。万能のソリューションはありません。
そのため、ルートディレクトリを削除するには、 1つだけであると仮定します。
unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "${f[@]}"
第2レベルのファイル/ディレクトリが最上位の親と同じ名前(たとえば、)になっていないことを確認してください/foo/foo
。しかし/foo/bar/foo
、/foo/bar/bar
大丈夫です。そうした場合、または単に安全にしたい場合は、抽出に一時ディレクトリを使用できます。
temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"
Bashを使用している場合、トップレベルが単一のディレクトリであるかどうかをテストできます:
f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] && echo "Single dir!"
Bashといえばdotglob
、隠しファイルを含めるためにオンにする必要があり、すべてを単一の便利な関数でラップできます。
unzip-strip() (
local zip=$1
local dest=${2:-.}
local temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
shopt -s dotglob && local f=("$temp"/*) &&
if (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] ; then
mv "$temp"/*/* "$dest"
else
mv "$temp"/* "$dest"
fi && rmdir "$temp"/* "$temp"
)
それをあなたの~/.bashrc
orに入れれば、もう~/.profile
心配する必要はありません。単に次のように使用します:
unzip-strip sourcefile.zip mysubfolder
(mysubfolder
存在しない場合は自動的に作成されます)
のマニュアルページunzip
でそのようなオプションを見つけることができなかったので、これは不可能だと思います。:(
ただし、(状況に応じて)回避することができます。たとえば、zipファイル内の唯一の最上位ディレクトリの名前にfoo-
バージョン番号が続いていることが確実な場合、次のようにすることができます。
cd /tmp
unzip /path/to/file.zip
cd foo-*
cp -r . /path/to/destination/folder
rm -rf foo-*
潜在的に危険なので、意図的に追加しませんでした。という名前のフォルダーが既にあった場合はどうなりますfoo-bar
か?抽出は/tmp
フォルダ内で行われていることに注意してください。フォルダは時々自動的に空になります。
&&
、前のステップが成功した場合にのみ特定のステップが発生するため、すべてのステップがエラーなしで完了したrm
場合にのみ、最後のステップ()が実行されます。
/tmp/some-hardcoded-folder-name
、一時フォルダーとしてユーザーを使用mktemp
することはできませんが、代わりにそのために使用する必要があります。それは、そのような既存のフォルダーがないことを保証します。以下の私の答えを確認してください。
-j
ジャンクパスに使用できます(ディレクトリを作成しないでください)。これは、ある程度一般的な単一レベルのアーカイブにのみお勧めします。マルチレベルのディレクトリ構造を持つアーカイブは平坦化されます-これにより、抽出するファイルの名前の衝突が発生する可能性さえあります。
unzipのmanページから:
-j junk paths. The archive's directory structure is not recreated; all files are deposited in the extraction directory (by default, the current one).