![ファイル数に基づいて zip アーカイブを作成する](https://rvso.com/image/89166/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E6%95%B0%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%84%E3%81%A6%20zip%20%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B.png)
サンOS5.8
ディレクトリ構造
/テスト/CHM
CHM
A
file1.txt
file2.txt
B
file3.txt
C
file4.txt
file5.txt
file6.txt
親ディレクトリ CHM に 8 個未満のファイル/サブディレクトリがある場合は、通常どおり zip で圧縮します。親ディレクトリ CHM に 8 個以上のファイル/サブディレクトリがある場合は、5 つのファイルごとに zip アーカイブを作成します。これはテスト専用です。実稼働環境では、5 個ではなく 10000 個のファイルになります。親ディレクトリ CHM には、0 個から n 個のサブディレクトリを含めることができます。
#!/bin/bash
set -e
cd $subdir/
# vars
num=8 # set 10000 in production
for dir in $subdir
do
dir=${dir%*/}
# testing code only
if [[ ${dir##*/} = "CHM" ]]
then
numfile=$(ls * | wc -l)
fi
if [ "$numfile" -lt "$num" ]
then
zip -r -6 ${dir##*/}.zip .
else
ls * > files
split -l 5 - files < files
for i in files[a-z][a-z]; do
zip -6 "$i.zip" -@ < "$i"
done
fi
# end test
done
exit
zip warning: name not matched: A:
zip warning: name not matched: file1.txt
zip warning: name not matched: file2.txt
zip warning: name not matched: B:
zip error: Nothing to do! (filesaa.zip)
2 番目の if ステートメントの else 部分が失敗していますが、その理由はわかりません。以下を作成しようとしています:
CHM.zip master
CHM.001.zip
CHM.002.zip
CHM.003.zip
したがって、リモート サーバー上で同じ順序で解凍できます。
答え1
あなたのルールに完全に従ったかどうかはわかりませんが、標準ユーティリティを使用する方が簡単かもしれません(そして、何をいつ作成するかについてのルールを簡素化します)。
find . -type f | split -d -a3 -l $num --filter='zip -@ $FILE.zip' - "$pfx".
find
は明らかなので、好みに合わせてオプションを調整してください。出力を に渡す前にリストをソートしたい場合がありますsplit
。
split
:
- d
- アルファベットの接尾辞の代わりに番号を使用する-a3
- 接尾辞の長さ(番号付け) 3桁(この場合は数字)-l
- カウンターを増やす行数--filter=COMMAND
- ファイルに書き込む代わりにコマンドに行を渡すCOMMAND
- は通常書き込みに使用されるファイル名として$FILE
解釈されるsplit
ため、一重引用符で囲む必要があります(または、上記のコマンドラインを実行するシェルによる解釈を防ぐためにバックスラッシュで囲む必要があります)。-
- 標準入力の解析を明示的に要求する"$pfx".
好みのプレフィックス。ドットは意図的なものであり、split
自動的に追加されるものではありません。
答え2
Sun Solaris で動作するソリューションがあります。これは、各マルチパート zip ごとに 10000 個のファイルを圧縮し、マスター zip をリモート サーバーに scp します。
#!/usr/bin/env bash
#
#------------------------------------------------------------
#-- Zip up content files based on $1 parameter
#------------------------------------------------------------
function zip_files {
SRC="/ads/data02/CTS/Data/$1"
#-- destination folder
DST="/ads/acct/oracle/CTS"
#-- amount of files that should go in each zip file
FILES_PER_ZIP=10000
#-----------------------------------------------------------
FILES="/tmp/multizip.$$"
ZIP_PREFIX=$(basename $SRC)
#-- generate the list of the files to zip
find $SRC > $FILES
#-- zip the files
NUM=0
ZIP_NUM=1
printf -v ZIPFILE "$DST/$ZIP_PREFIX%03d" $ZIP_NUM
while read -r line; do
echo $line | sed -e 's/.*/"&"/' | xargs zip -6 $ZIPFILE
((NUM++))
if [ $NUM -eq $FILES_PER_ZIP ]; then
NUM=0
((ZIP_NUM++))
printf -v ZIPFILE "$ZIP_PREFIX%03d" $ZIP_NUM
fi
done < $FILES
#-- generate master zip file
/usr/bin/ls $DST/${ZIP_PREFIX}*.zip | xargs zip $DST/$ZIP_PREFIX
#-- perform cleanup
function finish {
/usr/bin/rm $FILES
/usr/bin/rm /ads/acct/oracle/CTS/${ZIP_PREFIX}[0-9][0-9][0-9].zip
}
trap finish EXIT
}
#------------------------------------------------------------
#-- Main processing
#------------------------------------------------------------
for dir in /ads/data02/CTS/Data/*/
do
d=$(basename $dir)
zip_files $d
scp "/ads/acct/oracle/CTS/${d}.zip" [email protected]:/var/www/html/CTS/Content/A/TMP
/usr/bin/rm -f "/ads/acct/oracle/CTS/${d}.zip"
done
exit