作者 主題: 寫一個自動更改檔名的批次檔  (閱讀 8801 次)

0 會員 與 1 訪客 正在閱讀本文。

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
寫一個自動更改檔名的批次檔
« 於: 2009-10-22 17:15 »
小弟寫一個批次檔,想把 Exchange SPAM Archive Mail 檔名去掉年份
程式如下,但是實際執行起來,一直發生錯誤... :(

代碼: [選擇]
for /F "tokens=*" %I in ( 'dir *.eml /s /b' ) do (
set FullPath=%I
set OldName=%~nxI
set NewName=%OldName:~4%
ren "%FullPath%" "%NewName%"
)

dir /s /b 會產生 Full Path 的檔案清單
所以只要擷取檔名,使用 %~nx 參數 ( n→ File Name , x→Ext. File Name )
擷取原始檔名第五碼開始用 %OldName:~4%

如果是要抓開始到第 M 碼,就用 %OldName:~,M%
如果是要抓 N 碼到 M 碼就用 %OldName:~N,M%

錯誤發生在第四行
程式顯示是 set NewName=%OldName:~4%
也就是說 %OldName:~4% 的值並沒有設定給 NewName

然後第五行的 rename 指令會產生 The system cannot find the file specified. 錯誤訊息。

但是程式執行完後,執行 echo %FullPath% 或是 echo %FileName%
顯示內容都是對的....

不知道程式哪裡出錯了....唉

底下是 Windows XP Command Line Reference
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds.mspx?mfr=true
« 上次編輯: 2009-10-22 17:18 由 湯包 »
人必先置於死地而後生
科技來自人性
想像是科技之母

slime

  • 俺是博士!
  • *****
  • 文章數: 1692
    • 檢視個人資料
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #1 於: 2009-10-22 17:25 »
在第三行之後先加個 echo %OldName% 看看. (再各行都加一些 echo 跟 pause 檢查看看)

另外批次檔內有些地方要用 %% 代替 %
« 上次編輯: 2009-10-22 17:31 由 slime »
冷笑話: 我的 IP 是 127.0.0.1

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #2 於: 2009-10-22 17:39 »
我試過了,echo %OldName%
顯示的內容是 正確的檔名,
但是 echo %NewName
顯示的內容是 %OldName:~4%
我想大概是 %Variable:~n,m% 的功能,必須是要已經存在 Shell 裡的變數
或者說,Batch File 裡的變數,不會存到 Shell,所以第四行、第五行發生錯誤。
人必先置於死地而後生
科技來自人性
想像是科技之母

slime

  • 俺是博士!
  • *****
  • 文章數: 1692
    • 檢視個人資料
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #3 於: 2009-10-22 18:07 »
剛剛不用 for 的話是正常的, 給您參考看看.
代碼: [選擇]
set OldName=1000 333
echo %OldName%
set new=%OldName:~2%
echo %new%
冷笑話: 我的 IP 是 127.0.0.1

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #4 於: 2009-10-22 18:19 »
但是加上 for 就會出問題... :(
人必先置於死地而後生
科技來自人性
想像是科技之母

eose

  • 活潑的大學生
  • ***
  • 文章數: 499
  • 性別: 男
    • 檢視個人資料
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #5 於: 2009-10-22 19:05 »
請參考這篇看看 http://phorum.study-area.org/index.php?topic=31769.0
小弟也還再try  :P
« 上次編輯: 2009-10-22 19:07 由 eose »

洋蔥叔叔

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 830
    • 檢視個人資料
    • 洋蔥叔叔的隨意漫談電腦、網路、.NET、軟體本地化、雜七雜八
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #6 於: 2009-10-22 21:45 »
最前面加

setlocal EnableDelayedExpansion

然後除了%I 以外的變數改用 ! 試試

代碼: [選擇]
setlocal EnableDelayedExpansion

for /F "tokens=*" %%I in ( 'dir *.eml /s /b' ) do (
set FullPath=%%I
set OldName=%%~nxI
set NewName=!OldName:~4!
ren "!FullPath!" "!NewName!"
)

這邊有解釋:
http://batcheero.blogspot.com/2007/06/how-to-enabledelayedexpansion.html

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #7 於: 2009-10-23 13:30 »
感謝呀,這樣就可以正常Work了 ^_^


藉由使用 setlocal 及 endlocal 命令,您甚至可以進一步在 Cmd.exe 的例項 (或在指令檔中) 中,進行本機的變更。Setlocal 會建立本機領域,而 endlocal 會終止本機領域。丟棄在 setlocal 及 endlocal 領域中所做的任何變更,從而保持原始環境不變。您可以將這兩個命令巢狀為 32 等級的最大值。如需 setlocal 及 endlocal 命令的相關資訊,請參閱 Setlocal 及 Endlocal。

http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/setlocal.mspx?mfr=true
人必先置於死地而後生
科技來自人性
想像是科技之母

Taurus

  • 可愛的小學生
  • *
  • 文章數: 2
    • 檢視個人資料
回覆: 寫一個自動更改檔名的批次檔
« 回覆 #8 於: 2009-12-03 00:46 »
引用
for /F "tokens=*" %%I in ( 'dir *.eml /s /b' ) do (
set FullPath=%%I
set OldName=%%~nxI
call set NewName=%%OldName:~4%%
call ren "%%FullPath%%" "%%NewName%%"
)