Home > Back-end >  Trying to concatenate the last 10 lines of a log file to a batch variable using powershell
Trying to concatenate the last 10 lines of a log file to a batch variable using powershell

Time:11-10

I'm new to Windows scripting, but have quite a lot of experience in bash and python.

Here's the issue. Whenever I run this, (and this is the best result I've gotten so far) it makes it most of the way through and then errors with "The filename, directory name, or volume label syntax is incorrect."

Ignore the code designed for newlines, I'm still fighting with that as well.

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%

The reason I'm taking the substring is because some of the lines in the logfile start with < and > . I thought that was my only issue, but that is not the case. Please let me know if any more info is needed. Thank you!

CodePudding user response:

Changed

echo %LAST_TEN%
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

to

echo !LAST_TEN!
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Note: Your own answer shows the effective solution, but I thought I'd provide some background information.

Squashman has provided the crucial pointer:

  • Switching from echo %LAST_TEN% to echo !LAST_TEN! avoids problems with metacharacters (special characters such as < and >) in the variable value.

  • The alternative would be to double-quote the variable reference - echo "%LAST_TEN%" - but, sadly, the double quotes are then included in the output.

In other words: If you need to echo the value of a variable that (potentially) contains metacharacters unquoted:

  • Place setlocal EnableDelayedExpansion at the start of your batch file.
  • Then reference the variable of interest as !VAR! instead of %VAR%: the delayed expansion this results in prevents the value to become part of the source-code line that cmd.exe parses (due to the macro-style up-front expansion that happens with %VAR%).

A simplified example:

@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!

Scoping enabling of setlocal enableDelayedExpansion:

One pitfall of delayed expansion is that that all ! characters are then considered part of delayed variable reference, typically resulting in their quiet removal; e.g., echo hi! outputs just hi. To escape ! characters in literal strings that should be used verbatim, you need ^^! (sic) in unquoted strings, and ^! inside "...".

The escaping is also needed for %...% variable references (e.g., echo %var:!=^^!%), but is again avoided for !...! ones.

To avoid such escaping headaches you can enable setlocal enableDelayedExpansion on demand, for a given line or block of lines, and disable it again with 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!

Caveat: Since setlocal creates a copy of the environment variables, which endlocal then discards, do not try to set variables between setlocal and endlocal if you need later code to see these changes.

  • Related