findstr not able to accept string from multiple FOR loop - windows

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

Related

File count and size of each folder

I have the following batch script which gives the size of each folder in a directory. I need help in tweaking this or creating a new script so it gives the file count of each folders as well:
#echo off
setlocal disabledelayedexpansion
set "folder=%~1"
if not defined folder set "folder=%cd%"
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
endlocal
All the information is already in the output of the inner dir command, you only need to change what to retrieve
#echo off
setlocal disabledelayedexpansion
for %%a in ("%~f1.") do set "folder=%%~fa"
for /d %%f in ("%folder%\*") do (
set /a "size=0", "files=0", "directories=0"
for /f "tokens=1,3,5" %%a in ('
dir /-c /a /w /s "%%~ff\*" 2^>nul ^| findstr /b /c:" "
') do if "%%~c"=="" (
set "files=%%~a"
set "size=%%~b"
) else set /a "directories=%%~a/3"
setlocal enabledelayedexpansion
echo(%%~nxf # !size! bytes : !files! files : !directories! directories
endlocal
)
Add this cmd at the end and it will count files in a given dir
setlocal enableextensions
set count=0
for %%x in ("%folder%\*") do set /a count+=1
echo %count%
endlocal
This is inefficient tho, as you are traversing the whole directory twice.
Ideally, you need to combine the two FOR loops into one, just scan the dir once and add the size to the size counter and do count+=1 for each.
Try something like *added spacing to show what i added
set "folder=%~1"
if not defined folder set "folder=%cd%"
set count=0
for /d %%a in ("%folder%\*") do (
set "size=0"
for /f "tokens=3,5" %%b in ('dir /-c /a /w /s "%%~fa\*" 2^>nul ^| findstr /b /c:" "') do if "%%~c"=="" set "size=%%~b"
set /a count+=1
setlocal enabledelayedexpansion
echo(%%~nxa # !size!
endlocal
)
echo %count%
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

count length of filenames in batch

my problem is I want to count the length of multiple filenames and save this numbers into a file.
My approach is this:
#echo off
for %%i in (*.txt) do (
set Datei=%%~ni
call :strLen Datei strlen
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
echo.%strlen%>> tmp
)
The problem here is it only works for the first filename and after that it is stuck and does not go on to the next filename.
Just for another alternative, findstr can output the offset of each matching line. Using it over the dir output and substracting the offset of the previous line from the current one (and the CRLF at the end of the line), we get the length of the previous line / file name
#echo off
setlocal enableextensions disabledelayedexpansion
set "lastOffset=0"
for /f "tokens=1,* delims=:" %%a in ('(dir /b *.txt ^& echo(^) ^| findstr /o "^"') do (
if %%a gtr 0 (
set /a "size=%%a - lastOffset - 2"
setlocal enabledelayedexpansion
echo(!fileName! !size!
endlocal
)
set "lastOffset=%%a"
set "fileName=%%b"
)
Just for another alternative of a one-line command:
for %# in (*.txt) do #for /F "delims=:" %G in ('(echo "%~f#"^&echo(^)^|findstr /O "^"') do #if %~G NEQ 0 ( <^NUL set /p "dummy=%~f#|%~z#|"&set /a %~G-5&echo()
or the same in a bit more readable form:
for %# in (*.txt) ^
do #for /F "delims=:" %G in ('(echo "%~f#"^&echo(^)^|findstr /O "^"') ^
do #if %~G NEQ 0 ( <^NUL set /p "dummy=%~f#|%~z#|"&set /a %~G-5&echo()
Unfortunately, unlike the cmd shell, set command does not display its result in a batch script. Therefore, we need to set a string length to an environment variable and then echo its value with delayed expansion enabled:
#ECHO OFF >NUL
SETLOCAL EnableExtensions EnableDelayedExpansion
rem file lengths:
rem for %%A in (*.txt) do echo Name:%%A, Length: %%~zA
rem full path lengths:
for %%# in (*.txt) do (
for /F "delims=:" %%G in ('(echo "%%~f#"^&echo(^)^|findstr /O "^"') do (
if %%~G NEQ 0 (
set /a "length=%%~G-5"
rem echo(%%~f#^|%%~z#^|!length!
echo(%%~f#^|!length!
)
)
)
A slightly modified how to do count length of file name.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
(
for /f "tokens=*" %%A in ('dir *.txt /B /S /A:-D ^| findstr /IV "_output.txt"') do (
set "name=%%~nA"
#echo "!name!">"%TMP%\_Temp.txt"
for %%I in ("%TMP%\_Temp.txt") do (
set /a "length=%%~zI"
set /a length-=4
#echo !length!:'!name!'
)
)
)> _output.txt 2>&1
del "%TMP%\_Temp.txt"
MORE /C /P _output.txt
ENDLOCAL
EXIT /B 0
well the solution was coming from you i just moved the parts out of the loop. the code is this:
#echo off
for %%i in (*.txt) do (
set Datei=%%~ni
call :strLen Datei strlen
)
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1
goto :strLen_Loop
(endlocal & set %2=%len%)
echo.%strlen%>> tmp

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.
)

Batch string search iterating over all files in a folder

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

Resources