尝试使用 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,如果您需要稍后的代码来查看这些更改,请不要尝试在 setlocalendlocal 之间 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"