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
Related
I want this following for-loop to output the findings of these two searches in one line in the All_Metadata.txt
for %%a in (*.txt) do (
findstr /B "589" %%a
findstr /X /C:"1 1,96 " %%a
) >> All_Metadata.txt
This For-Loop output looks like this:
58998545
1 1,96
Instead of (this is what it should look like):
58998545 1 1,96
Operating System: Windows 10
Capture the output of the both findstr commands into variables with for /f loops and echo them together (no need for a variable with the second one; just use the for variable):
#echo off
setlocal ENABLEDELAYEDEXPANSION
for %%a in (*.txt) do (
set "b="
set "c="
for /f "delims=" %%b in ('findstr /B "589" "%%a"') do set "b=%%b"
for /f "delims=" %%c in ('findstr /i /X /C:"1 1,96 " "%%a"') do set "c=%%c"
echo(!b! !c!
)
Another way is, to use the set /p trick to write the first findstr result without a line feed and just add the result from the second findstr (doesn't need delayed expansion):
#echo off
setlocal
for %%a in (*.txt) do (
set "b="
for /f "delims=" %%b in ('findstr /B "589" "%%a"') do <nul set /p "=%%b "
findstr /i /X /C:"1 1,96 " "%%a"
)
I was able to list mp4 files in a directory with a for loop, and depending on how many files are listed, a parameter is passed to the choice command. What I wasn't able to do is to select a file from a list that has been created with a for loop? This way I hope to use the selected file in another command as a parameter.
Here my code:
#echo off
setlocal enableextensions enabledelayedexpansion
set /a count = 0
echo.
for %%f in (*.mp4) do (
set /a count += 1
echo [!count!] %%f
)
for /l %%a in (1,1,%count%) do (
call set "cOpt=%%cOpt%%%%a"
)
echo.
choice /C %cOpt% /M "Select input video:"
echo %errorlevel% # selected option is shown here but no filename
endlocal
#Echo Off & SetLocal EnableExtensions
:Menu
For /F "Delims==" %%G In ('(Set File[^) 2^> NUL') Do Set "%%G="
For /F "Tokens=1,* Delims=[]" %%G In ('(Set PATHEXT^=^) ^& %__AppDir__%where.exe ".":"*.mp4" 2^> NUL ^| %__AppDir__%find.exe /N /V ""') Do Set "File[%%G]=%%~nxH" & Echo %%G. %%~nxH
If Not Defined File[1] GoTo :EOF
:Select
Set "#="
Set /P "#=Choose a file from the list by entering its item number. "
For /F "Tokens=1,* Delims==" %%G In ('(Set File[%#%]^) 2^> NUL ^| %__AppDir__%find.exe "="') Do Set "File[#]=%%H"
If Not Defined File[#] GoTo Select
:Main
Echo You chose item number %#% which was assigned to "%File[#]%" & Pause
You would obviously modify the last line to be your required command with parameter.
If you wish to include the full paths, simply change both instances of %%~nxH on line 5, to %%H. Additionally if you wish to stipulate a location, instead of the current directory, change ".", on the same line to e.g. "Y:\our\Path".
I am developing a shell script that executes a command a returns a checksum string. This string is has each hexa separated with white spaces, something that I would like to remove and have, for example, 4AA512, instead of 4A A5 12 as command output but I am not able to find a solution that works. Here the script:
for /f "delims=" %%f in ('dir %~dp0*.zip /b') do (
echo %%~f:
for /f "delims=" %%a in ('certUtil -hashfile "%~dp0%%~f" SHA512 ^| find /i /v "SHA512" ^| find /i /v "certUtil"^') do (
echo %%a:' '=''%
)
set /a counter += 1
echo.
)
Anyone has a solution?
Thanks!
(answer moved from question/comment to - well - an answer)
Finally got a solution:
set counter=0
for /f "delims=" %%f in ('dir %~dp0*.zip /b') do (
echo %%~f:
for /f "delims=" %%a in ('certUtil -hashfile "%~dp0%%~f" SHA512 ^| find /i /v "SHA512" ^| find /i /v "certUtil"^') do (call :ShowChecksum "%%a")
set /a counter += 1
echo.
)
echo %counter% files(s) found.
pause
exit
:ShowChecksum
set "checksum=%~1"
set "checksum=%checksum: =%"
echo %checksum%
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
I have been working on this script for a little and I am new to writing batch files. I know my syntaxs is wrong and need some help.
#echo off
setlocal enabledelayedexpansion
set "ports=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports"
for /f %%I in ( 'reg query "%ports%"')
do (
echo %%I | findstr /i "c:\\convertdoc\\output\\silentprinttemp\\.*\.ps" >NUL
IF ERRORLEVEL 1 reg delete "%ports%" /v "%%I" /f
)
#echo off
setlocal
set "ports=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports"
for /f %%I in (
'reg query "%ports%"'
) do (
echo %%I | findstr /i "c:\\convertdoc\\output\\silentprinttemp\\.*\.ps" >NUL
IF ERRORLEVEL 1 reg delete "%ports%" /v "%%I" /f
)
As the comments also point out, cmd wants "do" on the same line as the closing parenthesis of the previous expression. You're not using delayed expansion. It's not an error, but I see no reason to turn it on.
#echo off
setlocal
set "ports=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports"
for /f %%I in ( 'reg query "%ports%"' ) do (
echo %%I | findstr /i "c:\\convertdoc\\output\\silentprinttemp\\.*\.ps" >NUL
IF ERRORLEVEL 1 reg delete "%ports%" /v "%%I" /f
)
Curiously, this experiment worked:
FOR /F %%i IN (
'dir /b'
) DO (
#ECHO %%i
)