2015-01-14 38 views
0

這是我的第一篇文章,所以如果格式不符合它的原因,請原諒我。 (對於Batchfile:從日誌文件中讀取最後一行並將它們複製到一個新文件

改進建議,歡迎。)

我想創建一個批處理文件,將讀取日誌文件的最後幾行,並將它們複製到一個新的文件。

直到現在,我發現here一種方式來讀取最後一行。

代碼會是這樣的:

for /f %%i in ('find /v /c "" ^< someFile.txt') do set /a lines=%%i 
set /a startLine=%lines% - 1 
more /e +%startLine% someFile.txt > lastLines.txt 

上面的代碼適用於一個文件的時間。我需要的是讀取已知列表中所有文件的最後一行,並將此行添加到新的.csv文件中。

我一直在使用下面的代碼用於獲取日誌文件中的第4個條目,但它返回每個日誌文件的每一行:

for /f %%x in (%list%) do for /f "delims=.txt, tokens=4" %%i in (%%x.txt) do echo %%x, %%i >> output.csv 

什麼我需要是一種兩者結合的,但我不不知道如何合併它們,並將完整的最後一行復制到.csv文件中。

=== @Magoo: Thanx爲您的反應。 在每個日誌文件中可以用1到> 100行用逗號分隔信息。例如:

"LOGON,6-1-2015,12:43:39,USERNAME,HOSTNAME,,,,192.168.209.242,00:21:5A:2E:64:5E" 

第4個條目的最後一個代碼用於獲取已登錄到計算機的所有帳戶的列表。這段代碼給了我所有在%list%中檢查過的計算機日誌上的所有登錄/註銷事件的列表。 在%list $中,我有我想要檢查的所有日誌文件的名稱。這返回所有行。

對於新的批處理文件,我只需要最後一次登錄/註銷條目,我希望整個最後一行。

所以我有一個.txt文件,我需要檢查所有計算機的主機名。 這個.txt文件將通過變量%list%逐行讀取。

從每個日誌文件我只需要最後一行復制到輸出文件。

=== 我剛試過由JosefZ提供的解決方案。不幸的是,這並不適用於我。沒有最後一行被複制到結果文件。在代碼中,我刪除了可能的最後一行的額外條目,因爲日誌中沒有空行,我還添加了一個條目用於我希望在結果中可用的主機名。 JosefZ的文件名爲:

@ECHO OFF >NUL 
@SETLOCAL enableextensions disabledelayedexpansion  
type nul>output.csv  
set "list=_listing.txt" 
for /F "tokens=*" %%x in ('type "%list%"') do (
    set "host=%%~x" 
    for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G" 
    call :lline 
)  
:endlocal 
@ENDLOCAL 
goto :eof  
:lline  
    set "filename=.\logs\%filename:&=^&%.txt" 
    echo %host%,%lastline%>>output.csv 
goto :eof 

結果文件只顯示主機名。我會更多地瞭解這一點,但所有的提示都歡迎!

=== 明白了!

@ECHO OFF >NUL 
@SETLOCAL enableextensions disabledelayedexpansion 

type nul>output.csv 

set "list=_listing.txt" 
for /F "tokens=*" %%x in ('type "%list%"') do (
    set filename= :: *empty previous filename* 
    set lastline= :: *empty previous lastline* 
    set "host=%%~x" 
    set "filename=.\logs\%host%.txt" :: *creating the filename from path+hostname+extention* 
    for /F "tokens=*" %%G in ('type "%filename%"') do set "lastline=%%G" 
    call :lline 
) 

:endlocal 
@ENDLOCAL 
goto :eof 

:lline 

    echo %host%,%lastline%>>output.csv 

goto :eof 
+0

因此 - 對於列表中的每個文件名,您想要什麼信息?這是什麼「第4項?」你想從日誌文件的每一行加上整個最後一行的「第4項」?你知道你的「delims」規範意思是「分隔符是'''或't'或'x'或','或'space'」 - 'delims'是一組字符,而不是一個字符串。向我們展示一個示例行,將其編輯到您的問題中,並說明您要提取哪些數據。 – Magoo

回答

0

如果文件有更多尾隨空行,那麼使用行編號的方法可能會失敗。幸運的是for /F循環忽略(不迭代)空行;讓我們把使用這個功能:腳本中使用的下一步做法:

  • disabledelayedexpansion,允許在文件名
  • set "list=_listing.txt"其中_listing.txt包含文件名列表(完整路徑和擴展.txt包括)!,一個文件命名在一行:由dir /b /s *.txt>_listing.txt
  • type nul>files\output.csv得到清空輸出文件(可選)
  • set "lastline=!!!file empty!!!"初始化變量%lastline%;可能是set "lastline="以及
  • call :lline處理變量%filename%%lastline%
  • set "filename=%filename:&=^&%",允許在文件名&

該腳本如下:

@ECHO OFF >NUL 
@SETLOCAL enableextensions disabledelayedexpansion 
type nul>files\output.csv 

set "list=_listing.txt" 
for /F "tokens=*" %%x in ('type "%list%"') do (
    set "filename=%%~x" 
    set "lastline=!!!file empty!!!" 

    rem the whole line 
    for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G" 

    rem the fourth token only 
    rem for /F "tokens=4" %%G in ('type "%%~x"') do set "lastline=%%G" 

    call :lline 
) 
:endlocal 
@ENDLOCAL 
goto :eof 

:lline 
    set "filename=%filename:&=^&%" 
    echo %filename% %lastline% 
    rem >>files\output.csv 
goto :eof 

樣品_listing.txt文件:

d:\bat\files\1exclam!ation.txt 
d:\bat\files\2exc!lam!ation.txt 
d:\bat\files\11per%cent.txt 
d:\bat\files\12per%cent%.txt 
d:\bat\files\17per%Gcent.txt 
d:\bat\files\18per%%Gcent.txt 
d:\bat\files\21ampers&nd.txt 
d:\bat\files\22ampers&&nd.txt 

輸出:

d:\bat>lastlines 
d:\bat\files\1exclam!ation.txt 0 15.01.2015 1:52:28.48 -15072 20465 
d:\bat\files\2exc!lam!ation.txt 6 15.01.2015 1:52:28.50 3250 16741 
d:\bat\files\11per%cent.txt -8 15.01.2015 1:52:28.50 -3692 27910 
d:\bat\files\12per%cent%.txt !!!file empty!!! 
d:\bat\files\17per%Gcent.txt 0 15.01.2015 1:52:28.56 14508 12374 
d:\bat\files\18per%%Gcent.txt 1 15.01.2015 1:52:28.56 30540 26959 
d:\bat\files\21ampers&nd.txt 15.01.2015 1:22:50.18 
d:\bat\files\22ampers&&nd.txt 15.01.2015 1:22:50.18 

真的,所有鎮流器是用於(可能的)在尾隨文件和(可能)!和在只有文件名&空線;全部都可以用

for /f %%x in (%list%) do for /f "skip=%startLine% tokens=4" %%i in (%%x) do echo %%x, %%i >> output.csv 
+0

Thanx JosefZ 讀你的劇本,這似乎是我需要的。我會嘗試一下,並回來的結果ASAP – Armand0

+0

你好JosefZ, 剛剛試過你的代碼,它不適合我。請閱讀原始問題了解更多詳情。 – Armand0

+0

@ JosefZ - 你的答案是溶劑的基礎。非常感謝! – Armand0

0

您應該使用一個簡單的FOR迭代值列表,而不是FOR/F。

類似下面應該工作:

@echo off 
setlocal enableDelayedExpansion 
>>output.csv (
    for %%F in (
    "file1.log" 
    "file2.log" 
    "file3.log" 
    etc. 
) do (
    for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1 
    more +!skip! %%F 
) 
) 

周圍的文件名引號是沒有的情況下,你會得到一個名稱用空格。

你可以使用你的LIST變量,如果它看起來像
set LIST="file1.log" "file2.log" "file3.log" etc.

@echo off 
setlocal enableDelayedExpansion 
set LIST="file1.log" "file2.log" "file3.log" etc.  
>>output.csv (
    for %%F in (%LIST%) do (
    for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1 
    more +!skip! %%F 
) 
) 

的東西,如果你的任何文件名中包含的字符!,則必須切換你的循環中延遲擴展開和關。否則,當擴展%%F時,延遲擴展會破壞名稱。

@echo off 
setlocal disableDelayedExpansion 
set LIST="file1.log" "file2.log" "file3.log" etc.  
>>output.csv (
    for %%F in (%LIST%) do (
    for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1 
    setlocal enableDelayedExpansion 
    more +!skip! %%F 
    endlocal 
) 
) 
+0

謝謝dbenham。 您的解決方案使我可以將所有文件名放入批處理文件中,同時將它們放入文件中。這將是額外的工作,但值得一試,當沒有其他解決方案。 – Armand0

+0

@ Armand0 - 啊,現在我明白你爲什麼使用FOR/F了。如果每行只有一個文件路徑,那麼FOR/F將對該文件起作用。但是,如果每個文件路徑都嵌入到更大的行中,則解析它可能會很複雜。這一切都取決於文件格式。 – dbenham

相關問題