![根據檔案數量建立 zip 存檔](https://rvso.com/image/89166/%E6%A0%B9%E6%93%9A%E6%AA%94%E6%A1%88%E6%95%B8%E9%87%8F%E5%BB%BA%E7%AB%8B%20zip%20%E5%AD%98%E6%AA%94.png)
太陽操作系統5.8
目錄結構
/測試/CHM
CHM
A
file1.txt
file2.txt
B
file3.txt
C
file4.txt
file5.txt
file6.txt
如果父目錄 CHM 的檔案/子目錄少於 8 個,則正常壓縮。如果父目錄 CHM 有 8 個或更多檔案/子目錄,則為 5 個檔案建立一個 zip 檔案。這僅用於測試。在生產中,它將是 10000 個文件,而不是 5 個。
#!/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)
第二個 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
通常用於寫入的檔案名,這意味著它必須用單引號引起來(或反斜線以防止執行上述命令行的 shell 進行解釋)-
- 明確要求解析標準輸入"$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