私は読んだこれ。しかし、私は少し違うことを達成しようとしています。
多くのサブディレクトリがあるディレクトリがあります。これらのサブディレクトリを使用して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
...