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"
ParseRat is an old program that I have had a long time. I need to transpose text files in c:\wherefilesare.
I run the below and it just dies:
echo on
setlocal EnableDelayedExpansion
cd c:\wherefilesare
SET progdir=C:\program files (x86)\ParseRat
for%%x in (*.txt) do ("%%progdir%\parserat.exe" "%%x.txt" "%%progdir%\test.prz" "%%x.csv"
As #Squashman says:
"You (have) an extra percent symbol for all your (environment) variables. You are also not using the FOR meta-variable correctly. Essentially %%x expands to the actual file name with the extension. So it will see file1.txt.txt and file1.txt.csv. You need to use the command modifiers. %%~nx to get just the file name without the extension."
Also, you are missing a closing parenthesis...
echo on
setlocal EnableDelayedExpansion
cd c:\wherefilesare
SET progdir=C:\program files (x86)\ParseRat
for %%x in (*.txt) do (
"%progdir%\parserat.exe" "%%~nx.txt" "%progdir%\test.prz" "%%~nx.csv"
)
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.
I can't figure out how to get my audio extractor script working via commandline arguments on ahk. I know the command line argument is correct, as I'm able to get it working through a batch file, but I keep getting the error below. I think I'm probably doing something wrong syntactically but I just can't figure out what.
I'd really appreciate any help. Thanks.
Error: the following variable name contains an illegal character"
channels=2,samplerate=44100}:standard{access="file",mux=dummy,dst="%A_LoopField%.mp3"}
Code:
fileselectfile, File_Name, M3
SplitPath, File_Name, name
Loop, parse, name, `n
if a_index = 2
{
msgbox, %A_LoopField%
Run, "C:\Program Files\VideoLAN\VLC\vlc.exe" "-I dummy -v %File_Name% :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:standard{access="file",mux=dummy,dst="%A_LoopField%.mp3"}"
}
Here is the original batch code if you're curious about the audio extraction function I was talking about
#ECHO OFF
REM Loop through files (Recurse subfolders)
REM Syntax
REM FOR /R [[drive:]path] %%parameter IN (set) DO command
REM
REM Key
REM drive:path : The folder tree where the files are located.
REM
REM set : A set of one or more files. Wildcards must be used.
REM If (set) is a period character (.) then FOR will
REM loop through every folder.
REM
REM command : The command(s) to carry out, including any
REM command-line parameters.
REM
REM %%parameter : A replaceable parameter:
REM in a batch file use %%G (on the command line %G)
FOR /R %%G IN (*.mp3) DO (CALL :SUB_VLC "%%G")
FOR /R %%G IN (*.mp3.mp*) DO (CALL :SUB_RENAME "%%G")
GOTO :eof
:SUB_VLC
SET _firstbit=%1
SET _qt="
CALL SET _newnm=%%_firstbit:%_qt%=%%
SET _commanm=%_newnm:,=_COMMA_%
REM echo %_commanm%
ECHO Transcoding %1
REM Here's where the actual transcoding/conversion happens. The next line
REM fires off a command to VLC.exe with the relevant arguments:
CALL "C:\Program Files\VideoLAN\VLC\vlc" -I dummy -v %1 :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:standard{access="file",mux=dummy,dst="%_commanm%.mp3"} vlc://quit
REM Having no SLEEP-esque command, we have to trick DOS/Windows into pausing
REM for a bit between encode ops - To give the host OS a chance to do what it
REM needs to - Via clever use of the PING utility:
REM (Thanks to http://www.computing.net/answers/programming/dos-command-for-wait-5-seconds/11192.html for the tip! :-)
PING -n 1 -w 10000 1.1.1.1 > NUL
GOTO :eof
:SUB_RENAME
SET _origfnm=%1
SET _endbit=%_origfnm:*.mp3=%
CALL SET _newfilenm=%%_origfnm:.mp3%_endbit%=.mp3%%
SET _newfilenm=%_newfilenm:_COMMA_=,%
COPY %1 %_newfilenm%
GOTO :eof
:eof
REM My own little addition to prevent the batch window from "vanishing" without
REM trace at the end of execution, as if a critical error had occurred.
PAUSE
Have you tried without the SplitPath, File_Name, name? I got rid of the error like this, but I don't know if it produces the result you want in the end.
I found the answer. I was making syntatical errors I just didn't have the knowledge to fix myself. The new RUN statement works perfectly.
Here is the newly revised script
fileselectfile, File_Name, M3
SplitPath, File_Name, name, dir, ext, name_no_ext, drive
StringReplace, File_Name, File_Name,`n, \
Loop, parse, name, `n
{if a_index = 2
msgbox, %A_LoopField%
Run % "C:\Program Files\VideoLAN\VLC\vlc.exe -I dummy -v """ File_Name """ :sout=#transcode{vcodec=none,acodec=mp3,ab=128,channels=2,samplerate=44100}:standard{access=""file"",mux=dummy,dst=""" A_LoopField ".mp3""} "
}
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