Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 670 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why does for /f not ignore blank lines?

#1
I'm trying to get a simple value from a `for /f` loop in a batch file.

Using the command `wmic path win32_localtime get dayofweek` gives me the output:

C:\sendemail>wmic path win32_localtime get dayofweek
DayOfWeek
1


C:\sendemail>

So, using the following batch script, I should be able to return a result of "1":

set cmd=wmic path win32_localtime get dayofweek
for /f "tokens=1 skip=1" %%Z in ('%cmd%') do set _myday=%%Z
echo Var is %_myday%

But I don't, it sets the variable at least twice, as seen here :

C:\sendemail>set cmd=wmic path win32_localtime get dayofweek

C:\sendemail>for /F "tokens=1 skip=1" %Z in ('wmic path win32_localtime get dayofweek') do set _myday=%Z

C:\sendemail>set _myday=1

:\sendemail>set _myday=

C:\sendemail>echo Var is
Var is

C:\sendemail>

At first, I wondered why, then I realised the loop is processing the two blank lines... which it shouldn't be. according to this: [

[To see links please register here]

][1]

> Skip SKIP will skip processing a number of lines from the beginning of
> the file. SKIP includes empty lines, but after the SKIP is complete,
> FOR /F ignores (does not iterate) empty lines.

Either, it's not working normally, or those lines are not blank, and are filled with something...

At any rate, how do I get just the day of the week result out of this, and ignore the rest?


[1]:

[To see links please register here]

Reply

#2
This slight midification will work:

@ECHO OFF
set cmd=wmic path win32_localtime get dayofweek
for /f "tokens=1 skip=1" %%Z in ('%cmd%') do (
set _myday=%%Z
GOTO BREAK
)
:BREAK
echo Var is %_myday%
PAUSE

Simply jump out of the loop after reading the desired line.
Reply

#3
About the lines contents, yes, the output from `wmic` includes at the end of each line an additional carriage return character that is detected by the `for` command. That is the reason for your *non empty* lines.

You can try with

<!-- language: lang-dos -->

for /f "tokens=2 delims==" %%Z in ('
wmic path win32_localtime get dayofweek /value
') do for /f %%Y in ("%%Z") do set "_myday=%%Y"

The code is asking `wmic` to return the information in `key=value` format and using the equal sign to tokenize the input records. As we request only the second token, `for` will only process lines that return at least two tokens, lines having a key (first token), an equal sign (delimiter) and a value (second token)

But, the additional carriage return at the end of the line is also included in the value of the variable.

When the variable is used with normal syntax (`%_myday%`) it is not seen, but with delayed expansion (`!_myday!`) the additional carriage return will be echoed.

To remove this additional character from the variable, a second `for` command has been used in the posted code.
Reply

#4
The above is a good approach and intitially I applied it successfully. Because of another need to capture a WMI variable and load into an environment variable, I wanted some that would be a native command line. I stumbled on this...

for /F "skip=2 tokens=2 delims=," %%i IN ('wmic timezone get Bias /format:csv') do (echo var Bias=%%i; > %TZONEDB%mid.htm )

The core is that using the CSV format makes skip work (no trailing blanks) and gives you easily parsed output.

ed g
Reply

#5
I recently had the issue discussed here and whilst previous answers helped I wanted to retrieve several variables for subsequent testing. At first I used code similar to the following example *(just not on explorer.exe and with different variable names. The following variable names have been deliberately chosen to match variable name restrictions in the later code)*.
````
setlocal
for /F "skip=2 tokens=2,3,4 delims=," %%a in ('
wmic /node:"MyFileServer-pc" process where Name^="explorer.exe"
get HandleCount^,
ParentProcessId^,
ThreadCount
/format:csv
') do (
set ProcHandleCount=%%a
set ProcParentProcessId=%%b
set ProcThreadCount=%%c
)
echo HandleCount %ProcHandleCount%, ParentProcessID %ProcParentProcessId%, ThreadCount %ProcThreadCount%
````
However, I dislike this solution as wmic always returns results in the order in which it internally iterates them disregarding the order in which they are presented to the wmic command, So the command `wmic process where Name^="explorer.exe" get ThreadCount^,HandleCount^,ParentProcessId` still returns ThreadCount last. This makes the previous code error prone when fetching multiple parameter value pairs and a hassle to get the ordering correct.

So instead I used the following code, which achieves the same result avoiding the need to care about the ordering of wmic parameters. It is also very easy to add additional parameters still with no need to care about ordering.
````
setlocal
for /F "tokens=1,2delims==" %%a in ('
wmic /node:"MyFileServer-pc" process where Name^="explorer.exe"
get HandleCount^,
ParentProcessId^,
ThreadCount
/value
') do @set Proc%%a^=%%b
echo HandleCount %ProcHandleCount%, ParentProcessID %ProcParentProcessId%, ThreadCount %ProcThreadCount%
````
In the above code, the variable naming is provided by the *parameter* of each returned *parameter=value* pair from wmic plus a fixed prefix, automatically matching returned parameter and value pairs. Note the use of a prefix, in this case 'Proc', without at least a one character prefix returned wmic blank lines cause errors. If different environment variable names are needed then the first solution allows freedom in naming and allows for shorter names but is more error prone when multiple values are required.
For what little it's worth... the following code avoids the variable prefixes and silences errors. More unique variable names would usually be desired.
````
(
for /F "tokens=1,2delims==" %%a in ('
wmic /node:"MyFileServer-pc" process where Name^="explorer.exe" get HandleCount^,ParentProcessId^,ThreadCount /value
') do @set %%a=%%b
) 2>nul
````
These examples use the wmic parameter /node:"MyFileServer-pc" to get remote process info but work equally for simpler wmic commands.
Reply

#6
I always use this batch template when processing wmic output:

setlocal enableextensions enabledelayedexpansion

for /f "delims and such" %%a in ('wmic path win32_localtime get dayofweek 2^>nul ^<nul') do (
set VAR=%%a
CALL :RMCRLF VAR
if "!VAR!" NEQ "" (
rem If we get here, then it's a non-empty line
rem ... Do something ...
)
)

GOTO :EOF
:RMCRLF
:: All this does is clean stray carriage returns/line feeds off of a variable,
:: which wmic is notorious for injecting into its output.
set RMCRVAR=%1
IF NOT DEFINED RMCRVAR GOTO :EOF
CALL set %RMCRVAR%=%%%RMCRVAR%%%
GOTO :EOF

They key here is the "function" (if you will) **:RMCRLF**. It will strip the pesky carriage returns off of a variable so you can check for true emptiness of the string, and then decide to skip the empty line.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through