複数のサブディレクトリを圧縮し、各zipファイルにN個のサブディレクトリを含める方法[閉じる]

複数のサブディレクトリを圧縮し、各zipファイルにN個のサブディレクトリを含める方法[閉じる]

私は読んだこれ。しかし、私は少し違うことを達成しようとしています。

多くのサブディレクトリがあるディレクトリがあります。これらのサブディレクトリを使用してzipファイルを作成したいのですが、各サブディレクトリごとに別々のzipファイルを作成するのではなく、グループ化したいと思います。各zipファイルに10個のサブディレクトリがあるとします。

編集:すべてのサブディレクトリは1レベルです!

とても感謝しています。

ベストアンサー1

したがって、グループ化しようとしているすべてのサブディレクトリは、親ディレクトリよりもある程度低いレベルにあると仮定します。私たちはzipサブディレクトリに再帰します。

編集する:人々の提案のおかげで、この新しいバージョンはスペース、改行、特殊文字を含む名前を含むすべての種類のファイル名を処理します。この問題に関する素晴らしい記事はここにあります。 https://unix.stackexchange.com/a/321757/439686

#!/bin/bash
export rootdir=${1:-/your/parent/directory}
export N=10 # group size
export stamp=$(date +%s)

find "$rootdir" -type d -mindepth 1 -maxdepth 1  -exec bash -c '
   count=0 # group number
   while [ $# -gt 0 ] ;do
     ((count++))
     zip -r "$rootdir/group.${stamp}.${count}.zip" "${@:1:N}"
     shift $N || set --
   done
' "" {} +

結果:

group.1615512971.1.zip
group.1615512971.2.zip
group.1615512971.3.zip
group.1615512971.4.zip
...

以下は、位置パラメータを繰り返すがサブシェルを生成しないいくつかの異なるバージョンです。 (このバージョンは以前のバージョンよりも速く動作します)

#!/bin/bash
rootdir=/your/parent/directory
N=10 # group size
stamp=$(date +%s)

readarray -td '' ARRAY < <(find "$rootdir" -type d -mindepth 1 -maxdepth 1 -print0)
set -- "${ARRAY[@]}"

count=0
while [ $# -gt 0 ] ;do
  ((count++))
  zip -r "$rootdir/group.${stamp}.${count}.zip" "${@:1:N}"
  shift $N || set --
done

編集#2:並列性とメモリ使用量

この記事を読んだ後: https://unix.stackexchange.com/a/321765/439686 私たちが多数のディレクトリを扱う場合、最初の2つのバージョンでいくつかの深刻な問題が発生する可能性があると思いました。メモリに重大な負担をかけることに加えて、最初のfindコマンドを実行する前にディレクトリ全体のリストを見つけるのを待っているため、非効率的ですzip。パイプラインを介して並列にタスクを実行すると、はるかに優れています。これにより、ファイルの数はもはや重要ではありません。これは私たちにできる唯一の正しい解決策を提供しますfind ... -print0 | xargs -0 command。なぜxargs?これは、リスト全体を待つのではなく、N引数で一度にコマンドを起動し、xargsパイプで連結されるゼロで区切られた文字列を処理できるためです。-print0改行を含むファイル名には他の文字が許可されているため、ゼロを区切り文字として使用する必要があります。追加ボーナスでxargsマルチコアシステムをより活用するために、複数のプロセスを同時に起動することもできます。だからここにあります:

#!/bin/bash
rootdir=${1:-/your/parent/directory}
N=10 # group size
mktemp --version >/dev/null || exit 1
stamp=$(date +%Y%m%d%H%M)
cores=$(nproc) || cores=1
export rootdir N stamp cores

find "$rootdir" -type d -mindepth 1 -maxdepth 1 -print0 \
  | xargs -r0  --max-args=$N  --max-procs=$cores  bash -c '
  zip -r "$(mktemp -u -p "$rootdir" group.$stamp.XXXXXX.zip)" "$@" ' ""

結果:

group.202103140805.7H1Don.zip
group.202103140805.akqmgX.zip
group.202103140805.fzBsUZ.zip
group.202103140805.iTfmj8.zip
...

おすすめ記事