Batch string search iterating over all files in a folder - windows

I have the code below. It may be messy but it works on one file at a time, in this case test1.OUT. What I am trying to do is to try and use some sort of wildcard name instead of test1.OUT and iterate the batch file over all .OUT files in a folder.
The other issue that I would run in to is that the output3.txt file would be overwritten each time. Is it possible to have each run of the batch file export the information and add it to output3.txt rather than overwritting previous information?
#echo off
setlocal EnableDelayedExpansion
rem Assemble the list of line numbers
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"Number of Error Taps: 0" test1.OUT') do (
set /A before=%%a-6, after=%%a+1
set "numbers=!numbers!!before!: !after!: "
)
rem Search for the lines
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" test1.OUT ^| findstr /B "%numbers%"') do echo %%b) > output.txt
set wildcard=%%G
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"Site Number:" test1.OUT') do (
set /A before=%%a-1, after=%%a+1
set "numbers=!numbers!!before!: !after!: "
)
rem Search for the lines
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" test1.OUT ^| findstr /B "%numbers%"') do echo %%b) > output1.txt
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"Number of Error Taps: 0" test1.OUT') do (
set /A before=%%a-50, after=%%a+1
set "numbers=!numbers!!before!: !after!: "
)
rem Search for the lines
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" test1.OUT ^| findstr /B "%numbers%"') do echo %%b) > output2.txt
copy output1.txt+output.txt+output2.txt output3.txt
#pause

example code:
#echo off &setlocal EnableDelayedExpansion
for %%a in (*.out) do call:process "%%~a"
goto:eof
:process
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"Number of Error Taps: 0" "%~1"') do (
set /A before=%%a-6, after=%%a+1
set "numbers=!numbers!!before!: !after!: "
)
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "%~1" ^| findstr /B "%numbers%"') do echo %%b)> "%~n1.txt"
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"Site Number:" "%~1"') do (
set /A before=%%a-1, after=%%a+1
set "numbers=!numbers!!before!: !after!: "
)
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "%~1" ^| findstr /B "%numbers%"') do echo %%b)> "%~n11.txt"
set numbers=
for /F "delims=:" %%a in ('findstr /I /N /C:"Number of Error Taps: 0" "%~1"') do (
set /A before=%%a-50, after=%%a+1
set "numbers=!numbers!!before!: !after!: "
)
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "%~1" ^| findstr /B "%numbers%"') do echo %%b)> "%~n12.txt"
copy "%~n11.txt" + "%~n1.txt" + "%~n12.txt" = "%~n13.txt"
exit /b

Related

How to batch-copy the 10 newest files to a directory in Windows?

I use the following script to keep only the newest 360 files (a year, daily-made backup) in the directory:
for /f "skip=360 eol=: delims=" %%F in ('dir /b /o-d /a-d *.*') do #del "%%F"
How to afterwards copy the newest 7 files to another directory?
#echo off
setlocal enableextensions disabledelayedexpansion
rem Three alternatives
rem Pure arithmetics
set "numFiles=7"
for /f "delims=" %%a in ('dir /b /o-d /a-d') do (
2>nul set /a "1/numFiles", "numFiles-=!!numFiles" && (
echo copy "%%~fa" x:\somewehere
)
)
rem Pure arithmetics 2 - No negation operator
set "numFiles=7"
for /f "delims=" %%a in ('dir /b /o-d /a-d') do (
2>nul set /a "1/numFiles", "numFiles-=1" && (
echo copy "%%~fa" x:\somewehere
)
)
rem Number list of files
set "numFiles=7"
for /f "tokens=1,* delims=:" %%a in ('
dir /b /o-d /a-d
^| findstr /n "^"
') do if %%a leq %numFiles% (
echo copy "%%~fb" x:\somewehere
)

findstr not able to accept string from multiple FOR loop

Codes as below:
im getting below error:
FINDSTR: No search strings
I have traced the error an its coming from here:
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "!FILENAME!" ^| findstr /B "%numbers%"') do (...
Script is working properly if Im replacing FILENAME variable with exact filename manually. But I need to put it in a loop to execute within multiple files..
for /r %%i in (LOG_FILE*.txt) do (
set FILENAME=%%~nxi
for /F "delims=:" %%a in ('findstr /I /N /C:"fin.700 " !FILENAME!') do (
set /A val1=%%a-3, val2=%%a+3, val3=%%a+4, val4=%%a+11, val5=%%a+13 , val6=%%a+29, val7=%%a+30
set "numbers=!numbers!!val1!: !val2!: !val3!: !val4!: !val5!: !val6!: !val7!: "
)
set FILENAME=!FILENAME:~0,-1!
echo !FILENAME!>>tmptmptmp.tmp
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "!FILENAME!" ^| findstr /B "%numbers%"') do (
set linestr=%%b
echo !linestr!
)
)
Working without the outer FOR loop
#echo off
setlocal EnableDelayedExpansion
setlocal enableextensions
rem Assemble the list of line numbers
set numbers=
if exist "tmp" del "tmp"
if exist "tmp2" del "tmp2"
if exist "tmp.txt" del "tmp.txt"
REM for /r %%i in (LOG_FILE*.txt) do (
REM set FILENAME=%%~nxi
set FILENAME=LOG_FILE14012015.txt
for /F "delims=:" %%a in ('findstr /I /N /C:"fin.700 " !FILENAME!') do (
set /A val1=%%a-3, val2=%%a+3, val3=%%a+4, val4=%%a+11, val5=%%a+13 , val6=%%a+29, val7=%%a+30
set "numbers=!numbers!!val1!: !val2!: !val3!: !val4!: !val5!: !val6!: !val7!: "
)
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "%FILENAME%" ^| findstr /B "%numbers%"') do (
set linestr=%%b
echo !linestr!
)
Thanks for the help guys. I did a workaround as im not able to force the findstr to work properly with my requirements. Did two separate batch script to handle the logic. Below is a copy in case anyone is interested.
bat file that will handle the outer for loop:
#echo off
setlocal EnableDelayedExpansion
setlocal enableextensions
::Script that will loop for multiple files and will call search.bat
if exist "tmp.txt" del "tmp.txt"
if exist "multiple_search.log" del "multiple_search.log"
#echo Starting search... >> multiple_search.log
for /r %%i in (LOG_FILE*.txt) do (
#echo Searching %%i >> multiple_search.log
call search.bat %%i
)
#echo Search completed... >> multiple_search.log
endlocal
Main bat file:
#echo off
setlocal EnableDelayedExpansion
setlocal enableextensions
set numbers=
if exist "tmp" del "tmp"
if exist "tmp2" del "tmp2"
set FILENAME=%1
for /F "delims=:" %%a in ('findstr /I /N /C:"fin.700 " !FILENAME!') do (
set /A val1=%%a-3, val2=%%a+3, val3=%%a+4, val4=%%a+11, val5=%%a+13 , val6=%%a+29, val7=%%a+30
set "numbers=!numbers!!val1!: !val2!: !val3!: !val4!: !val5!: !val6!: !val7!: "
)
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "%FILENAME%" ^| findstr /B "%numbers%"') do (
set linestr=%%b
echo !linestr!
echo !linestr!>>tmp
)
set delim==
for /f "tokens=1*" %%a in (tmp) do (
echo %%a|find "!delim!" >nul
if !errorlevel!==0 (echo %%a%%b >> tmp2) else (echo record=%%a%%b >> tmp2)
)
set counter=0
set var=
for /f "tokens=1* delims==" %%a in (tmp2) do (
set /a counter=!counter!+1
set var=!var!%%b
set var=!var: =!
set var=!var!,
if !counter! geq 7 (
echo !var! >> tmp.txt
set counter=0
set var=)
)
endlocal

Remove quotes from the string value of a variable

I am trying to count the lines of each text file in a directory on the condition that a text file with the same filename also exists in a second directory or one of its subdirectories. The script should count the lines of both files. Here's my code:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /R "C:\Users\ABC\Documents\" %%W IN (*.txt) DO (
FOR /R "C:\Users\XYZ\Documents\" %%J IN ("%%~nxW") DO (
IF EXIST "%%J" (
set "firstfile=findstr /R /N "^^" "%%W" | find /C ":""
FOR /F %%G in ('!firstfile!') do set firstfilelines=%%G
set "secondfile=findstr /R /N "^^" "%%J" | find /C ":""
FOR /F %%H in ('!secondfile!') do set secondfilelines=%%H
ECHO %%W has !firstfilelines! lines.
ECHO %%J has !secondfilelines! lines.
)
)
)
pause
It counts the lines of text files in the first directory C:\Users\ABC\Documents\ but not in C:\Users\XYZ\Documents\ because findstr cannot recognize the value of %%J as a file path because it puts quotes around the filename as in C:\Users\XYZ\Documents\folder\"file.txt". How do I get rid of these quotes?
Use dir /s /b to build a list of files in the second folder
Use find /c /v "" filename to count the lines faster
Use set /a to trim the spaces in the assignment of the number
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set "folder1=C:\Users\ABC\Documents\"
set "folder2=C:\Users\XYZ\Documents\"
FOR /R "%folder1%" %%W IN (*.txt) DO (
FOR /f "delims=" %%J in ('dir /s /b "%folder2%\%%~nxW"') DO (
IF EXIST "%%J" (
FOR /F "tokens=3 delims=:" %%G in ('find /c /v "" "%%W"') do set /a L1=%%G
FOR /F "tokens=3 delims=:" %%G in ('find /c /v "" "%%J"') do set /a L2=%%G
ECHO %%W has !L1! lines.
ECHO %%J has !L2! lines.
)
)
)
pause

create a batch file to get a ip address from a network interface name

I have servers with more than 2 network interfaces.
ie. Primary.nic, BEN.nic, HB.nic etc
Using the following lines I'm getting the IP from the last NIC:
for /f "tokens=2 delims=:" %%a in ('ipconfig ^| find "IP" ^| find "Address" ^| find /v "v6"') do (
set IPAddr=%%a
)
echo=%IPAddr%
I need to find the IP address from a specific NIC name ie. "BEN"
I've tried this too:
#echo on
setlocal ENABLEEXTENSIONS
setlocal EnableDelayedExpansion
set result=false
for /f "tokens=2 delims=:" %%a in ('ipconfig ^| "BEN.NIC" ^| find "IP Address"') do (
set IPAddr=%%a
)
echo %IPAddr%
It doesn't work.
Next script should work:
#ECHO OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion
set "nicFunName=wiredEthernet"
for /F "usebackq tokens=*" %%G in (
`wmic nic where "NetConnectionID='%nicFunName%'" get index /value^|find "="`) do (
rem echo G %%G
for /F "tokens=*" %%H in ("%%G") do (
rem echo H %%H
for /F "usebackq tokens=2 delims==" %%I in (
`wmic NICCONFIG where %%H get IPAddress /value`
) do (
rem echo I %%I
for /F "tokens=1,2 delims={,}" %%J in ("%%I") do (
echo IPv4=%%J IPv6=%%K
rem or without double quotes: echo IPv4=%%~J IPv6=%%~K
)
)
)
)
ENDLOCAL
goto :eof
Where the for loops are
%%G to retrieve the NIC index in Index=0 format applicable as next wmic query where clause condition
%%H to remove a superabundand and harmful carriage return (0x0D) from wmic output
%%I to retrieve the IPAddress by index in {"<ipv4>","<ipv6>"} format
%%J to split previous output
You could add a most outer loop as follows:
for %%m in (
"Primary.nic" "BEN.nic" "HB.nic"
) do (
rem all for... code here with
rem where "NetConnectionID='%%~m'"
rem or call a subroutine or call a batch etc.
)

Checking web servers and is not parsing both port 80 as well as port 8080 from configuration files on same server

Results of research today on this..
REF = How to parse xml file in batch (CMD)
NOTE: The comment from jeb to help parse out the port number from xml
SET results=%CD%\somelog.log
IF EXIST %results% DEL %results%
REM NOTE: THIS IS ALL ONE LINE!!!! ALL THE WAY DOWN TO THE PAUSE STATMENT.
FOR /F "usebackq tokens=1" %%q in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services ^| find /i "tomcat"`) DO
FOR /F "usebackq tokens=3" %%a in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services\%%~nxq /v ImagePath`) DO
FOR /F "tokens=1-2,* delims=:\" %%1 IN ("%%a") DO
FOR /F tokens^=1^,2^ delims^=^" %%A IN ('..\grep -m 1 "\<Connector port\=" \\some_server\%%1$\%%2\conf\server.xml') DO
ECHO "CHECKING WEB PAGE CONTENT FROM URL http://some_server:%%B/server_page.htm" 1>> %results% &&
..\WGET -q "http://some_server:%%B/server_page.htm" -O - | ..\GREP "Configuration framework is not loaded" 2>> %results% &&
..\WGET -q "http://some_server:%%B/server_page.htm" -O - | ..\GREP "Successfully acquired a database connection" 3>> %results%
pause
Current Result: is the resulting data is being redirected to the log file, but the results of the WGET with the Pipe through using GREP is not capturing to the log.
Have tried:
result >> log
result 1>> log
result2 2>> log
result3 3>> log
And is only capturing the result of the ECHO command in the final results.
Starting point: 2014-12-05
Let's figure out why we are not getting the serverport. I have figured this out, but now I need to figure this out and how to get to the first %serverport%. As requested, I have removed FINDSTR and have gone with GREP.
Specifically:
REM >> here is the problem: if we want to break out for the first port
SET serverport=%%B && GOTO :BREAK)
:break
SET serverport=%serverport: protocol=%
SET serverport=%serverport:"=%
And is because we break out of the script, it is not able to continue to the second instance of Apache Tomcat because of:
FOR /F "tokens=1-2* delims==" %%A IN ('..\grep "\<Connector port\=" %tpath%') DO (
SET serverport=%%B
goto :break
)
:break
SET serverport=%serverport: protocol=%
SET serverport=%serverport:"=%
So.. Let's see what is going on here..
Step 1, Let's create a DEBUG Batch Script. This will grab the server key for the Windows Service Name. For example, when you run NET STOP tomcat6 or NET START tomcat6 .. We don't want the full registry path, but just the key name. We can use the same construct when trying to determine a folder name in the file system, but this is from the registry.
echo test 1
FOR /F "usebackq tokens=1" %%q in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services ^| find /i "tomcat"`) DO echo %%~nxq
echo end of test 1
Step 1 results, Let's see what this does..If we take tester.bat > results.txt we see:
D:\WORK\Scripts\test>echo test 1
test 1
D:\WORK\Scripts\test>FOR /F "usebackq tokens=1" %q in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services | find /i "tomcat"`) DO echo %~nxq
D:\WORK\Scripts\test>echo tomcat6_1
tomcat6_1
D:\WORK\Scripts\test>echo tomcat6_2
tomcat6_2
D:\WORK\Scripts\test>echo end of test 1
end of test 1
Step 2, let's see what we get when we start looking for the server port..
NOTE:Each FOR line is all one line.. FOR.. IN.. DO.. FOR.. IN.. DO.. FOR.. IN.. DO.. FOR.. IN.. DO... (yes, that is four of them all in one line)
echo test 2
FOR /F "usebackq tokens=1" %%q in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services ^| find /i "tomcat"`) DO
FOR /F "usebackq tokens=3" %%a in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services\%%~nxq /v ImagePath`) DO
FOR /F "tokens=1-2,* delims=:\" %%1 IN ("%%a") DO
FOR /F "tokens=1-2* delims==" %%A IN ('..\grep "\<Connector port\=" \\some_server\%%1$\%%2\conf\server.xml') DO (SET serverport=%%B)
echo end of test 2
echo we are done
Step 2 results, Let's see what this does..If we take tester.bat > results.txt we see:
D:\WORK\Scripts\test>echo test 2
test 2
D:\WORK\Scripts\test>FOR /F "usebackq tokens=1" %q in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services | find /i "tomcat"`) DO FOR /F "usebackq tokens=3" %a in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services\%~nxq /v ImagePath`) DO FOR /F "tokens=1-2,* delims=:\" %1 IN ("%a") DO FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\%1$\%2\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>FOR /F "usebackq tokens=3" %a in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services\tomcat6_1 /v ImagePath`) DO FOR /F "tokens=1-2,* delims=:\" %1 IN ("%a") DO FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\%1$\%2\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>FOR /F "tokens=1-2,* delims=:\" %1 IN ("d:\tomcat_1\bin\tomcat6.exe") DO FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\%1$\%2\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\d$\tomcat_1\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>(SET serverport="80" protocol )
D:\WORK\Scripts\test>(SET serverport="8443" protocol )
D:\WORK\Scripts\test>(SET serverport="8009" protocol )
D:\WORK\Scripts\test>FOR /F "usebackq tokens=3" %a in (`reg query \\some_server\HKLM\SYSTEM\CurrentControlSet\services\tomcat6_2 /v ImagePath`) DO FOR /F "tokens=1-2,* delims=:\" %1 IN ("%a") DO FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\%1$\%2\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>FOR /F "tokens=1-2,* delims=:\" %1 IN ("d:\tomcat_2\bin\tomcat6.exe") DO FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\%1$\%2\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>FOR /F "tokens=1-2* delims==" %A IN ('..\grep "\<Connector port\=" \\some_server\d$\tomcat_2\conf\server.xml') DO (SET serverport=%B )
D:\WORK\Scripts\test>(SET serverport="8080" protocol )
D:\WORK\Scripts\test>(SET serverport="8443" protocol )
D:\WORK\Scripts\test>(SET serverport="8010" protocol )
D:\WORK\Scripts\test>echo end of test 2
end of test 2
D:\WORK\Scripts\test>echo we are done
we are done
I only want the first instance of the server port.
This server has two instances of tomcat:
port 80
port 8080
It would be simple if it was just this one server, but I have 30 servers I want to report on.
OK. I am pretty sure that I can create an answer for this. With the nested FOR..IN..DO structures four times, I think that is why I am not able to run the WGET and only the first ECHO works.. Here is where we are at with this code.
REF How to parse xml file in batch (CMD)
NOTE: The comment from #jeb to help parse out the port number from xml
SET servers=%CD%\monitored_computers.txt
SET results=%CD%\somelog.log
IF EXIST %results% DEL %results%
FOR /f "tokens=2-8 delims=.:/ " %%a IN ("%date% %time: =0%") DO ECHO PROCESS CHECK STARTED %%a/%%b/%%c %%d:%%e:%%f.%%g >> %results%
FOR /F "tokens=1-2* delims=," %%A IN (%servers%) DO (
REM NOTE: THIS IS ALL ONE LINE!!!! ALL THE WAY DOWN TO THE PAUSE STATMENT.
FOR /F "usebackq tokens=1" %%q in (`reg query \\%%A\HKLM\SYSTEM\CurrentControlSet\services ^| find /i "tomcat"`) DO
FOR /F "usebackq tokens=3" %%a in (`reg query \\%%A\HKLM\SYSTEM\CurrentControlSet\services\%%~nxq /v ImagePath`) DO
FOR /F "tokens=1-2,* delims=:\" %%1 IN ("%%a") DO
FOR /F tokens^=1^,2^ delims^=^" %%H IN ('..\grep -m 1 "\<Connector port\=" \\%%A\%%1$\%%2\conf\server.xml') DO
ECHO "http://%%A:%%I/some_page.htm" >> %CD%\servers.txt
pause
)
Hope this helps somebody.

Resources