Windows cmd - findstr and gawk or how would you pull the below data out - parsing

I was wondering if it's possible to use findstr and/or gawk to return the output of a windows cmd exactly how I need it to be. I'm currently returning the output raw, then stripping out the blank lines, and parsing out what I need. Just as a learning thing, I was hoping I could see how this can be done better.
The raw output:
Change 2086888 on 2012/01/23 by user1#server1
test_description_1.2.3.4#29816
Change 2086888 on 2012/01/23 by user1#server2
test_description2_4.5.6.7#29816
Change 2078677 on 2012/01/20 by user2#server1
test_description3_7.8.9.10#29816
I take that output and parse it out to this with php:
1. 2086888,test_description_1.2.3.4#29816
2. 2086888,test_description2_4.5.6.7#29816
3. 2078677,test_description3_7.8.9.10#29816
To make it a little easier on myself, I remove the blank lines from the output by piping it to findstr and using /V "^$". So it's | findstr /V "^$".
How can I get the output that I parse out with php directly from the command line?

for command in cmd.exe skips blank lines, so it may be easier to parse it this way:
#Echo Off
setlocal enabledelayedexpansion
set linenum=1
for /f "tokens=1,2" %%A in (output.txt) do #(
if %%A==Change set result=%%B
if not %%A==Change (
echo !linenum!. !result!,%%A
set /a linenum=!linenum!+1
)
)
endlocal

Related

Pinging Hostnames from a Parsed File and Logging in Batch

I'm still pretty new to batch but I wanted to try out some different functionalities within the same batch program. Essentially, I am attempting to parse through a .txt file of hostnames and ping them 1 time each, and return a pass or fail by utilizing a find query for the specific ping result. The second find query is redundant but left in. A string of "timed out" indicates that the host is down. I have been able to achieve this with this bulky code, but my actual ping statistics are no longer being written to this log file.
I'm not too familiar with the command pipeline character but it may just be incompatible for this specific use case. If I remove the piped command for the find query, it is able to write the output of the ping command just fine, but then I lose the utility of a return pass or fail value. Is this just a simple syntax error? I've tried moving the location of the actual write to file argument on the line itself but it hasn't worked. Also, why are the errorlevel values inverted (line 21)? I can't seem to return what I'm looking for.
Is there anyway I can get all these parts to play nice together? I apologize if the answer is quite obvious...
#echo off
setlocal
set hosts=temp.txt
set count=0
echo.
echo Parsing File: %hosts%
echo.
echo Start > C:\Users\___\Downloads\pingLOG.txt
for /F "tokens=*" %%i in (%hosts%) do (
set /A count=count+1
echo+
echo.
echo [+] Pinging: %%i
echo [+] Pinging: %%i >> C:\Users\___\Downloads\pingLOG.txt
echo.
ping -n 1 "%%i" | find /I "timed out" >> C:\Users\___\Downloads\pingLOG.txt
if errorlevel == 1 (
echo Pass
) else (
echo Fail
)
echo.
echo %TIME% >> C:\Users\___\Downloads\pingLOG.txt
)
echo.
echo %count% Hosts Scanned
find /c "timed out" C:\Users\___\Downloads\pingLOG.txt
echo.
pause
You can't filter the output for a certain string and expect the complete output (eliminating unwanted parts is the very reason for filtering).
To accomplish your goal, you need a temporary file (the complete output) and filter that file, so you have both variants (filtered and unfiltered) (suboptimal, but well...):
ping -n 1 "%%i" >"%temp%\temp.tmp"
find /I "timed out" "%temp%\temp.tmp" >nul && set "status=Fail" || set "status=Pass"
type "%temp%\temp.tmp" >> "C:\Users\___\Downloads\pingLOG.txt"
echo %status% >> "C:\Users\___\Downloads\pingLOG.txt"

how to escape empty lines from end of command result

i use the following command to create a variable from my CPU Name:
#echo off
Rem create variable from cpu name
for /f "useback tokens=* skip=1" %%g in (`wmic cpu get name ^|findstr /i "."`) do (
set CPU_NAME=%%g
echo %CPU_NAME%
)
but the result is nothing, because there is some empty lines at end of "wmic cpu get name" command result and remove created variable
how can i solve it?
thanks a lot
Please search SO for delayed expansion.
call echo %%CPU_NAME%%
should show you the required data. This is one of several well-documented solutions.
There are some empty lines at the end of wmic cpu get name
Use findstr as follows to strip blank lines from the wmic output. You also need to use delayed expansion
Corrected batch file (test.cmd):
#echo off
setlocal enabledelayedexpansion
Rem create variable from cpu name
for /f "useback tokens=* skip=1" %%g in (`wmic cpu get name ^| findstr /r /v "^$"`) do (
set CPU_NAME=%%g
echo !CPU_NAME!
)
endlocal
Example usage:
> test
Intel(R) Core(TM) i5-2410M CPU # 2.30GHz
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
enabledelayedexpansion - Delayed Expansion will cause variables to be expanded at execution time rather than at parse time.
findstr - Search for strings in files.
wmic - Windows Management Instrumentation Command.
There is no need to echo the result within the for loop in your case because you are only setting a single name. Just echo it later.
#Echo Off
For /F "Skip=1 Delims=" %%A In ('WMIC CPU Get Name'
) Do For /F "Delims=" %%B In ("%%A") Do Set "CPU_NAME=%%B"
Echo=%CPU_NAME%
The second For loop is intended to remove the unwanted 'empty lines' you reported.

parse batch line by line

i am trying to parse the output of another function which is output line by line. to understand the function, it returns several lines of parameter and numbers like "top=123456789" or "low=123456789" (without the quotations) -
i try to parse the lines now with
for /F "delims=" %%a in ('%%I ^| findstr top') do set updir=%%1
set "updir=%1:~4%"
echo. %updir%
i am trying to get the pure numbers by trimming the known keywords like top, which would need then to be set to a var to return (%~1% ???) to a calling function back (other batch file).
could anyone help me with this please? shure it would be better to trim right from "=".
UPDATE:
this is the code returning the lines from the script i linked. i tried several ways to parse the return but i seem to be blind or too stupid to see, all is going weird.
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (
rem process the HTML line-by-line
org echo(%%I
try1 (echo %%I|findstr top
try2 for /F "delims=" %%a in ('%%I ^| findstr top') do set updir=%%a
try2 echo. %updir%
try3 for /F "delims=" %%a in ('%%I') do findstr top
try3 echo. %2%
)
didn't work either
for /F "tokens=1,2delims==" %%a in ('%%I') do if %1 == top set updir=%%b
echo %updir%
i tried both delim version beneath (too the tokens/delims version) but i don't get it right.
UPDATE SOLUTION:
for the ones reading the question here some additional comment:
rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"
rem test that trimmed line matches "variable=number"
to find a single item like e.g. "top" you have to add "to" or adjust whole first token
echo !line! | findstr /i "^to[a-z]=[0-9]" >NUL && (
rem test was successful. Scrape number.
for /f "tokens=2 delims==" %%x in ("%%I") do set "value=%%x"
echo !value!
)
If all you wish to do is to is to skip all lines until you find one that matches "text=numerals", then scrape the numeric portion of that line, all you need to do is this:
for /f "delims=" %%I in ('cscript /nologo /e:jscript "%~f0" "%URL%"') do (
rem trim whitespace from beginning and end of line
for /f "tokens=*" %%x in ("%%~I") do set "line=%%x"
rem test that trimmed line matches "variable=number"
echo !line! | findstr /i "^[a-z]*=[0-9]*$" >NUL && (
rem test was successful. Scrape number.
for /f "tokens=2 delims==" %%x in ("%%I") do set "value=%%x"
)
)
I think that's right, anyway. I didn't test it.
But I suspect that this is not going to work as you intend, since what you are scraping will probably include HTML tags. We will probably not be able to help you scrape the HTML unless you pastebin the HTML source of an example page, and explain what you wish to scrape from that source example.
does this fit your needs?
for /F "delims=" %%a in ('type file.txt ^| findstr "top low"') do set /a %%a
set top
set low
echo %top%, %low%
Try this:
for /F "tokens=2delims==" %%a in ('findstr top file.txt') do set "updir=%%a"
echo.%updir%
According to your comment my new code:
#echo off &setlocal enabledelayedexpansion
set "string=%%I"
set "string=!string:*top=!"
for /f "delims== " %%z in ("!string!") do set "string=%%z"
echo !string!
.. output:
123456789
Edit2: "added.

How to access different lines in text files batch

To clarify it First i'm making a url shortener script that use input.txt file as input and outputs as an output.txt where you can put unlimited links in the input.txt
This is what i got
#echo off
set /p firstline=<input.txt
echo %firstline%
for %%a in (%firstline%) DO (
set "text=http://adfoc.us/api/?key=c803bc5b2f2e8ad5ccb0166d4bc898ae^&url=%%a"
)
echo %text%>output.txt
example input.txt has 600 lines and i want to make them all in output.txt
I assumed that you have an input.txt file that contain 600 lines with just the url part, and that you want to complete that lines with fixed http and key parts. If this is true, then the Batch file below do that:
#echo off
(for /F "delims=" %%a in (input.txt) DO (
echo http://adfoc.us/api/?key=c803bc5b2f2e8ad5ccb0166d4bc898ae^&url=%%a
)) >output.txt
Antonio
PS - If my answer is right, then you are NOT making an "url shortener script", but precisely the opposite thing! This script take an url and enlarge it by adding http and key parts, isn't it?

Noobs approach to automate x264 cmd

so here is my script to loop through specific video extensions » add a manual profile » generate necessary *.bat & finally a final 'loader' batch file to execute previous *.bat files sequentially & necessary logging (this gives quiet a deal of freedom if you so want)
::==
:: gets lines into vars c1 v2 v...
#echo off
:: user input required
cd /d "d:\Trainers\out\"
setLocal EnableDelayedExpansion
dir /B /O:N | findstr ".wmv$ " >filename.txt
echo. >log.txt
:: user input required
for /f "tokens=* delims= " %%a in ('type filename.txt ^|findstr ".wmv$"') do (
set /a n+=1
echo. >file!n!.bat
set in=%in%%%a
:: user input required
set out=!in:.wmv=.mp4!
:: user input required
set v=x264 --crf 23 --level 3.1 --tune film -o "d:\Trainers\out\!in!" "d:\Trainers\out\!out!"
echo. !v!>file!n!.bat
)
dir /B /O:N | findstr ".bat$ " >x264_home.txt
for /f "tokens=* delims= " %%a in (x264_home.txt) do (
set /a n+=1
:: mtee is an external library Google it
set "z=call %%a | mtee /d/c/t/+ log.txt"
echo. !z! >> x264_home.bat
)
echo. #echo off > newFile.bat
type x264_home.bat >> newFile.bat
type newFile.bat > x264_home.bat
del newFile.bat,x264_home.txt,filename.txt
echo. pause >> x264_home.bat
echo. #echo All Operation done... >> x264_home.bat
:: user input required
move "d:\Trainers\out\*.bat" "d:\Program Files\x264_auto\test\"
:: user input required
move "d:\Trainers\out\log.txt" "d:\Program Files\x264_auto\test\"
::==
Now the above code which is fairly easy to understand (bcz its written by a noob) run perfectly & create necessary files. For instance one of the file1.bat looks like this:
x264 --crf 23 --level 3.1 --tune film --preset veryslow --deblock -2:-1 --zones 24233,25324,q=20 --acodec aac --abitrate 80 -o "d:\Trainers\out\1.wmv" "d:\Trainers\out\1.mp4"
...& the loader .bat file looks like
#echo off
call file1.bat | mtee /d/c/t/+ log.txt
call file2.bat | mtee /d/c/t/+ log.txt
call file3.bat | mtee /d/c/t/+ log.txt
#echo All Operation done...
You see this is a quiet flexible approach in that you can use special filestr » set another loop » set another profile. Furthermore every batch file can be latter edited especiialy when you heavily use --zone x264 feature
I am successful because there is no error in any output ...but its the x264.exe (provider/compiler x264GUI) throws error which it otherwise don't?
d:\Program Files\x264_auto\test>x264 --crf 23 --level 3.1 --tune film --preset
veryslow --deblock -2:-1 --zones 24233,25324,q=20 --acodec aac --abitrate 80 -o
"d:\Trainers\out\1.wmv" "d:\Trainers\out\1.mp4"
ffms [error]: could not create index
lavf [error]: could not open input file
raw [error]: raw input requires a resolution.
x264 [error]: could not open input file `d:\Trainers\out\1.mp4' via any method!
its the x264 thats the culprit perhaps a senior guide is required here
Is your x264 compiled with mp4 input support? (I believe that needs lavc/lavformat, just download precompiled x264 from x264.nl which has all extras)
Do you get the same error if you run the same command directly? (not through bat files)
If yes, does it only happen when you use zones? (if it does, then post an example of your command line as x264 bug to x264-devel mailing list)
If no, are you sure you are running the exact same x264? (perhaps there are several in different places on your system)
I recommend doing what you're doing either (a) in python with subprocess.call(...) or (b) in cygwin/bash/shell script, or . bat files are pretty much the wrong answer to any problem :) The nice thing about either of those two is that they have simple, regular escaping rules for program arguments.

Resources