尝试使用 powershell 将日志文件的最后 10 行连接到批处理变量
Trying to concatenate the last 10 lines of a log file to a batch variable using powershell
我是 Windows 脚本的新手,但在 bash 和 python 方面有很多经验。
问题来了。每当我 运行 这个时,(这是我迄今为止得到的最好结果)它大部分都通过了,然后出现“文件名、目录名或卷标语法不正确”的错误。
忽略为换行符设计的代码,我也在为此苦苦挣扎。
setlocal EnableDelayedExpansion
set LF=^
set LAST_TEN=Here are the last 10 lines of the download log:
for /f "tokens=* usebackq" %%x in (`powershell -command "& {Get-Content download.log | Select-Object -last 10 | ForEach-Object {$_.substring(2)}}"`) do (
set LAST_TEN=!LAST_TEN!%%x
)
echo %LAST_TEN%
我使用子字符串的原因是因为日志文件中的某些行以 < 和 > 开头。我以为那是我唯一的问题,但事实并非如此。如果需要更多信息,请告诉我。谢谢!
已更改
echo %LAST_TEN%
至
echo !LAST_TEN!
注意:您的 显示了有效的解决方案,但我想我会提供一些背景信息。
Squashman给出了要害指针:
从echo %LAST_TEN%
切换到echo !LAST_TEN!
避免了变量[=73中的元字符(特殊字符如<
和>
)的问题=]值,这是导致您出现错误消息的原因。
替代方法是 双引号 变量引用 - echo "%LAST_TEN%"
- 但是,遗憾的是,双引号是 包含在输出中.
换句话说:如果您需要 echo
一个(可能)包含元字符的变量的值 未加引号 :
将 setlocal EnableDelayedExpansion
放在批处理文件的开头。
然后 将感兴趣的变量引用为 !VAR!
而不是 %VAR%
:delayed expansion 这会阻止该值成为 cmd.exe
解析 的源代码行的一部分(由于宏%VAR%
).
风格的前期扩展
- 顺便说一句:Loop 变量 - 例如代码中的
%%x
- 尽管使用 %
而不是 !
作为分隔符, 有必要 总是 以 延迟 的方式扩展,这就是 set LAST_TEN=!LAST_TEN!%%x
即使 没有 双引号括起通常需要的文字和值的双引号 non-包含元字符的延迟变量引用(例如
set "LAST_TEN=a < b"
)
一个简化的例子:
@echo off
setlocal enableDelayedExpansion
:: Define a sample variable
:: Note the "..." enclosing both the name and the value.
set "var=a value with metacharacters: < > & |"
:: Thanks to using !var!, echoing the value *unquoted* works
echo !var!
范围 setlocal enableDelayedExpansion
:
延迟扩展的一个缺陷是 所有 !
字符然后被认为是延迟变量引用的一部分,通常会导致它们 安静地删除;例如,echo hi!
只输出 hi
。
要 转义 !
字符 文字 应逐字使用的字符串,您需要 ^^!
(原文如此)在 unquoted 字符串,^!
inside "..."
.
%...%
变量引用(例如,echo %var:!=^^!%
)也需要转义,但再次避免 !...!
变量引用。
为了避免这种令人头痛的问题,您可以根据需要setlocal enableDelayedExpansion
为给定的行或行块启用,然后使用endlocal
再次禁用它:
@echo off
:: Define a sample variable
:: Note the "..." enclosing both the name and the value.
set "var=a value with metacharacters: < > & |"
:: Because setlocal enableDelayedExpansion is NOT (yet)
:: in effect, the use of "!" is not a problem.
echo hi!
:: Localize the use of delayed expansion
setlocal enableDelayedExpansion
echo !var!
endlocal
:: Use of "!" is again fine.
echo hi again!
警告:因为setlocal
创建了环境变量的副本,endlocal
然后discards,如果您需要稍后的代码来查看这些更改,请不要尝试在 setlocal
和 endlocal
之间 set 变量。
既然您已经在使用 PowerShell,为什么不让它来做驴子的工作呢?
抓取最后十行并将它们连接在括号内,例如:
For /F Delims^=^ EOL^= %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content 'download.log' | Select-Object -Last 10) -Join ''"') Do Set "LAST_TEN=%%G"
我是 Windows 脚本的新手,但在 bash 和 python 方面有很多经验。
问题来了。每当我 运行 这个时,(这是我迄今为止得到的最好结果)它大部分都通过了,然后出现“文件名、目录名或卷标语法不正确”的错误。
忽略为换行符设计的代码,我也在为此苦苦挣扎。
setlocal EnableDelayedExpansion
set LF=^
set LAST_TEN=Here are the last 10 lines of the download log:
for /f "tokens=* usebackq" %%x in (`powershell -command "& {Get-Content download.log | Select-Object -last 10 | ForEach-Object {$_.substring(2)}}"`) do (
set LAST_TEN=!LAST_TEN!%%x
)
echo %LAST_TEN%
我使用子字符串的原因是因为日志文件中的某些行以 < 和 > 开头。我以为那是我唯一的问题,但事实并非如此。如果需要更多信息,请告诉我。谢谢!
已更改
echo %LAST_TEN%
至
echo !LAST_TEN!
注意:您的
Squashman给出了要害指针:
从
echo %LAST_TEN%
切换到echo !LAST_TEN!
避免了变量[=73中的元字符(特殊字符如<
和>
)的问题=]值,这是导致您出现错误消息的原因。替代方法是 双引号 变量引用 -
echo "%LAST_TEN%"
- 但是,遗憾的是,双引号是 包含在输出中.
换句话说:如果您需要 echo
一个(可能)包含元字符的变量的值 未加引号 :
将
setlocal EnableDelayedExpansion
放在批处理文件的开头。然后 将感兴趣的变量引用为
风格的前期扩展!VAR!
而不是%VAR%
:delayed expansion 这会阻止该值成为cmd.exe
解析 的源代码行的一部分(由于宏%VAR%
).- 顺便说一句:Loop 变量 - 例如代码中的
%%x
- 尽管使用%
而不是!
作为分隔符, 有必要 总是 以 延迟 的方式扩展,这就是set LAST_TEN=!LAST_TEN!%%x
即使 没有 双引号括起通常需要的文字和值的双引号 non-包含元字符的延迟变量引用(例如
set "LAST_TEN=a < b"
)
- 顺便说一句:Loop 变量 - 例如代码中的
一个简化的例子:
@echo off
setlocal enableDelayedExpansion
:: Define a sample variable
:: Note the "..." enclosing both the name and the value.
set "var=a value with metacharacters: < > & |"
:: Thanks to using !var!, echoing the value *unquoted* works
echo !var!
范围 setlocal enableDelayedExpansion
:
延迟扩展的一个缺陷是 所有 !
字符然后被认为是延迟变量引用的一部分,通常会导致它们 安静地删除;例如,echo hi!
只输出 hi
。
要 转义 !
字符 文字 应逐字使用的字符串,您需要 ^^!
(原文如此)在 unquoted 字符串,^!
inside "..."
.
%...%
变量引用(例如,echo %var:!=^^!%
)也需要转义,但再次避免 !...!
变量引用。
为了避免这种令人头痛的问题,您可以根据需要setlocal enableDelayedExpansion
为给定的行或行块启用,然后使用endlocal
再次禁用它:
@echo off
:: Define a sample variable
:: Note the "..." enclosing both the name and the value.
set "var=a value with metacharacters: < > & |"
:: Because setlocal enableDelayedExpansion is NOT (yet)
:: in effect, the use of "!" is not a problem.
echo hi!
:: Localize the use of delayed expansion
setlocal enableDelayedExpansion
echo !var!
endlocal
:: Use of "!" is again fine.
echo hi again!
警告:因为setlocal
创建了环境变量的副本,endlocal
然后discards,如果您需要稍后的代码来查看这些更改,请不要尝试在 setlocal
和 endlocal
之间 set 变量。
既然您已经在使用 PowerShell,为什么不让它来做驴子的工作呢?
抓取最后十行并将它们连接在括号内,例如:
For /F Delims^=^ EOL^= %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content 'download.log' | Select-Object -Last 10) -Join ''"') Do Set "LAST_TEN=%%G"