Info
#

2025/12/14 (Sun) 00:41:28 GMT+0000 (UTC)
Type: PC | System: Unknown | Browser: Unknown ... More

Menu
.
+
#
  • @ /note/bash/post-ExtractZipFiles
Content
.
+
#

Post: Nekoformi
Date: 2024/02

Extract Zip Files

GUIでは複数の圧縮ファイルを一括で展開するとき、全てをサブフォルダー付きで展開することができません。その問題を解決するために、簡易的なスクリプトを作成しました。

/usr/local/bin/extractZipFiles
+
#
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
#!/bin/bash target="$1" output="$2" format=".*\.(zip|ZIP|7z|7Z|tar|TAR|gz|GZ)" function extractFile() { local target="$1" local file="${target##*/}" local double if [[ "${file%.*}" =~ ^.*.(tar|TAR)$ ]]; then local file="${file%.*}" local double=true fi if [[ -n "$2" ]]; then local output="${2%/}/${file%.*}"/ else local output="${target%/*}/${file%.*}"/ fi if [[ -z "$double" ]]; then 7z x -o"$output" "$target" else 7z x -so "$target" | 7z x -si -ttar -o"$output" fi echo "Extract file ... ${target} -> ${output}" } export -f extractFile find "$target" -regextype posix-extended -regex "$format" -type f -print0 | xargs -0 -i bash -c "extractFile \"{}\" \"${output}\""
  • Bashのコマンドをファイルに記述する際は、1行目にシバン・シェバング(#!/bin/bash)を書くことで機能を明示します。
  • 文字列に空白( )が含まれる場合は空白をエスケープ(\ )するか、引用符(")で囲む必要があります。また、引用符の内部で引用符を記述する場合も同様にエスケープ(\")する必要があります。
  • 変数展開とパターンマッチ(${変数名(#|##|%|%%)パターン})を用いることでディレクトリーの抽出やパスの正規化を行います。
  • 7zコマンドで展開したデータをパイプ(|)で再び7zコマンドに渡すことで、また、その際に-soオプションと-siオプションを用いることで二重に圧縮されたファイル(.tar.gz等)を展開します。
  • 定義された関数(シェル関数)はxargsコマンドで呼び出せないため、exportコマンドと-fオプションで関数を環境変数に設定します。また、xargsコマンドではbashコマンドに-cオプションを付与することで文字列をコマンドとして実行します。
  • xargsコマンドは改行や空白を区切りとして処理するため、パスに空白が含まれると正常に動作しません。それを解決するため、findコマンドでは-print0オプションを付与することで一覧の区切りをNULL文字(/0)で記述します。また、xargsコマンドでは-0オプションを付与することでNULL文字を区切りとして処理します。
  • スクリプトは汎用性を考慮してPATHが通る場所に設置することが推奨されます。

スクリプトを実行すると、以下の結果となります。

~/Test Directory
+
#
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
- Test Folder A.zip - Test Folder - Test File - Test Folder B.zip - Test Folder - Test File - Test Folder C.zip - Test Folder - Test File - Test Folder D.7z - Test Folder - Test File - Test Folder E.tar - Test Folder - Test File - Test Folder F.tar.gz - Test Folder - Test File
Bash
+
#
1:
$ extractZipFiles ~/"Test Directory" ~/"Extract Directory"
~/Extract Directory
+
#
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
- Test Folder A - Test Folder - Test File - Test Folder B - Test Folder - Test File - Test Folder C - Test Folder - Test File - Test Folder D - Test Folder - Test File - Test Folder E - Test Folder - Test File - Test Folder F - Test Folder - Test File