2012-01-20 136 views
1

我想寫一個Windows批處理文件腳本,它將循環遍歷文件路徑的文本文件,使用每個文件路徑的數據做一些工作,然後最終刪除文件。For循環在批處理文件中讀取文件路徑的文件

我開始運行FORFILES命令,併發送其輸出(@ PATH參數是它匹配任何文件的完整路徑),文本文件(RESULTS.TXT)。

我結束了一個RESULTS.TXT文件是這樣的:

"C:/Windows/Dir1/fileA.log" 
"C:/Windows/Dir1/fileA.log" 
"C:/Windows/Dir2/fileC.log" 
"C:/Windows/Dir3/fileB.log" 

我想要做的是:

  • 使用for循環並閱讀RESULTS.TXT文件中的每一行
  • 對於每一行(文件路徑),去掉日誌文件所在的目錄名稱(即:Dir1,Dir2等),並在不同位置創建一個具有該SAME名稱的目錄(即.D :/ Archive/Backups/Dir1,D:/ Archive/Backups/Dir2等。) - 假設目錄doe不存在。
  • 將實際的.log文件移動到該目錄中的zip文件[我有代碼執行此操作]。
  • 從原始位置刪除.log文件。 [很簡單]

我很難搞清楚完成前兩步的最佳方法。我的循環似乎讀的第一行後停止:

FOR /F "tokens=1,2,3,4,5,6,7,8,9,10 delims=\" %%G in ("results.txt") DO (
... 
) 

回答

2

你不想用tokens/delims選項解析路徑,因爲你不知道你處理的目錄級別有多少。你想保留每一行的完整。分析要使用FOR變量修飾符的路徑。 (從命令行鍵入HELP FOR並查看輸出的最後一部分)

%%〜pG給出路徑(不包含驅動器或文件名)。如果我們刪除最後的\,我們可以通過另一個FOR迭代並使用%%〜nxA來獲取文件目錄的名稱(和可能的擴展名)。

延遲擴展的切換僅用於防止路徑中可能的!。如果你知道沒有路徑包含!那麼你可以簡單地在腳本的頂部啓用延遲擴展並完成它。

編輯 - 由於Aacini指出我誤讀了這些要求,所以此代碼已被顯着修改。它應該現在滿足要求。

for /f "usebackq delims=" %%G in ("results.txt") do (
    set "myPath=%~pG" 
    setlocal enableDelayedExpansion 
    for /f "eol=: delims=" %%A in ("!myPath:~0,-1!") do (
    endlocal 
    if not exist d:\Archive\Backups\%%~nxA md d:\Archive\Backups\%%~nxA 
    rem ::zip %%G into zip file in the D: location 
    rem ::you should be able to create the zip with the move option 
    rem ::so you don't have to del the file 
) 
) 
+1

但沒有任何修飾的給予最後的目錄路徑......在這個例子中,在d目錄:比一個位於C不同: – Aacini

+0

@Aacini - 啊,我沒看過問題足夠小心。我會再試一次 – dbenham

+0

謝謝@dbenham。只是一個小小的更正 - 設置myPath行不需要雙引號。 results.txt也沒有。我不確定它是否會使results.txt無效,但絕對是myPath。通過這些更正,我可以得到任何新的dirs,並且壓縮應該非常簡單。 – tresstylez

0

你有兩個小問題:

  • 文件中的路徑分隔符是「/」,但你在使用「\」 for循環。
  • 「results.txt」周圍的引號使其停止工作。

This works。不要在results.txt中寫引號,並且在文件名末尾不會得到引號。

@echo off 
FOR /F "tokens=3,4 delims=/" %%I in (results.txt) DO (
    REM Directory 
    echo %%I 
    REM File 
    echo %%J 
) 
1

在卸載到SFTP之前,我已經寫了這個文件給時間戳文件。

希望你覺得它有用。

時間戳編碼看起來可能與您的問題無關,但我將其留下,因爲它是剖析文件名本身的一個很好的例子。

我建議你在REN命令前加一個ECHO進行測試。不同的殼可能會有不同的結果。

最後,delayedexpansion命令不是必需的。這是子例程,用循環內的變量解決了我的問題。這可能是因爲我的操作系統版本。 (Win 8.1) - 離開它不會有什麼傷害。

@echo off 
cls 
setlocal enabledelayedexpansion 
if %time:~0,2% geq 10 set TIMESTAMP=%date:~10,4%%date:~4,2%%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2% 
if %time:~0,2% leq 9 set TIMESTAMP=%date:~10,4%%date:~4,2%%date:~7,2%_0%time:~1,1%%time:~3,2%%time:~6,2% 

echo TimeStamp=%TIMESTAMP% 
echo. 

for %%G in (*.txt) do (
set OLDNAME=%%G 
call :MXYZPTLK 
) 

dir *.txt 

goto :EOF 

:MXYZPTLK 
echo OldName=%OLDNAME% 
ren %OLDNAME% %OLDNAME:~0,-4%_%TIMESTAMP%%OLDNAME:~-4,4% 
echo. 

:END