这是我的第一个帖子,所以如果格式不符合预期,请原谅我。 (建议
欢迎改进。)我正在尝试创建一个批处理文件,它将从日志文件读取最后一行并将它们复制到新文件中。
到目前为止,我发现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: 谢谢你的反应。 在每个日志文件中可以是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 :(得分:1)
如果文件中有更多尾随空行,则使用行号的方法可能会失败。幸运的是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
答案 1 :(得分:1)
您应该使用简单的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
)
)
如果您的任何文件名包含!
字符,则必须在循环内切换延迟扩展ON和OFF。否则,延迟扩展将在%%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
)
)