iT邦幫忙

0

批次檔相同檔名進行壓縮與刪除特定清單

請教會寫批次檔高手,
小弟有個自動壓縮的批次檔想要執行,
希望達到的條件有下面幾點:

  1. 指定的目錄下,依照相同2個檔案,以及相同檔案名稱作為壓縮(解壓縮後只有相同2個檔案)。
  2. 可執行7zip的多執行緒。(因檔案容量大需求)
  3. 可以控制同時進行壓縮的動作,且目錄下多檔案時,判斷相同檔名(副檔名非相同都壓縮為同1個)。
  4. 不壓縮目錄下特定檔案。
    例如: 目錄下有A.cas、A.doc、B.cas、B.doc、C.cas、C.doc、D.cas、D.doc、pic.jpg,將指定範圍檔案移到批次檔同時進行3個壓縮動作,且比對A.cas、A.doc檔名相同壓縮成1個zip,其餘檔案全部被壓縮完畢,並且排除pic.jpg不壓縮(特定清單.txt要排除pic.jpg)。

目前程式遇到問題:

  1. 指定範圍檔案移到批次檔只能執行1個壓縮。
  2. 無法將特定檔案排除。
  3. 檔案名稱相同無法完整比對,請壓縮zip檔案只有檔案(不要有資料夾)
  4. 或是否可使用powershell簡化程式和判斷

目前批次檔內容

@echo off
set a=c:\program files\7-zip\7z.exe
for %%a in (%*) do (
dir /a %%a|findstr "DIR" >nul 2>nul && (
"%a%" a -tzip "%%~dpa%%~na.zip" "%%~a\*" -xr@特定清單.txt
) || (
"%a%" a -tzip "%%~dpa%%~na.zip" %%a -xr@@特定清單.txt
)
)

2 個回答

2
japhenchen
iT邦超人 1 級 ‧ 2020-11-11 07:18:53

給你一個觀點,既然要用powershell,不如考慮用python當批次檔用,對檔案處理的彈性大且有可擴展的7z壓縮元件可用,多執行緒也可以實現

https://pypi.org/project/py7zr/

看更多先前的回應...收起先前的回應...

你唯一要做的,就是在你的電腦上安裝python直譯器(跟powershell的意思差不多,也是要另外安裝或新系統內建)

沒有相容現有的程式碼的考慮的話,直上3.9即可
https://www.python.org/downloads/windows/
(記得加入path)

牢記一件事,python並非windows原生,所以資料夾的反斜線 \ 一定要改成正斜線(除號 / ),不然會有很大的機會找不到檔案
例:C:/windows/system32/drivers/etc/hosts

主要考量以bat或powershell為主,
因移植到他台電腦需再安裝python, 故不考慮python作法

僅提供另一種思路而已,我用C#編譯成EXE執行檔來解決這個需求,MSSQL資料庫備份檔BAK壓縮成7Z並切割成500MB為基本單位的備份群,然後一個個以SCP複製到異地LINUX主機上去,避免單檔過大,傳送中途失敗的機率很大沒辦法忽視,LINUX主機上的備份為7天一個周期來ROTATE,目前已運作超過2年,規叢喝賀

另外....PYTHON是可以編譯成單一EXE帶著走,連安裝包都不用,很綠色的程式

https://medium.com/pyladies-taiwan/python-%E5%B0%87python%E6%89%93%E5%8C%85%E6%88%90exe%E6%AA%94-32a4bacbe351

至於bat跟ps1想做到多執行緒.....我做不到,有請各大高手來解答了

1
蟹老闆
iT邦大師 1 級 ‧ 2020-11-12 00:13:40

請參考
說明:
Folder 來源資料夾
Thread 同時執行的數量
Wait 當同時執行的數量達到指定時等待多久重新偵測,新開的執行動作時間長時可增加秒數
[O] 這個變數必須是一個空白字元
Par 取得的同檔案名.不同副檔名集合,不含路徑

@Echo OFF
Title Pseudo Daemon .......
SetLocal ENABLEDELAYEDEXPANSION
Set Folder=d:\test\test\
Set Thread=5
Set Files=1
Set FileTotal=0
Set Wait=1
Set [O]= 
CD /D %Folder%
(For /f "delims=*" %%i In ('Dir /A-D /B /O-N /L "%Folder%"') Do Set [O]%%~ni="%%~nxi" ![O]%%~ni!)||(Echo 找不到檔案可進行操作&Pause&Exit)
For /f %%i In ('Set [O]^|Find /V /C ""') Do Set FileTotal=%%i&Goto :Next
:Start
Cls
Set Current=1
Echo Action = %Files% / %FileTotal%
Echo.    工作階段	 PID	    記憶體用量
For /f "eol=資 skip=1 tokens=2-5" %%a In ('TaskList /NH /FI "WINDOWTITLE eq %Thread%Thread"') do (
	Echo. 	%%c	%%a		%%d   			
	Set /a Current =!Current!+1
)
If %Files% GEQ %FileTotal% Goto :EOF
IF Not %Current% GTR %Thread% Goto :Next
Timeout /t %Wait%&Goto :Start
:Next
For /F "Skip=%Files% Delims== tokens=2*" %%i in ('Set [O]') Do Set Par=%%i&Goto :One
:One
::這裡用來放要執行的命令,將 "timeout /t 5" 修改成要執行的命令
Start /min "%Thread%Thread" "%SystemRoot%\system32\cmd.exe" /c "TimeOut /t 5"
Set /a Files +=1
Goto :Start

這個批次檔改造自DOS批次檔同時執行多個壓縮

我要發表回答

立即登入回答