Batch script to compare text file to folder contents - batch-file

I have this batch to check export a list of programs installed and their uninstallers:
#ECHO OFF
setlocal ENABLEDELAYEDEXPANSION
MKDIR "%userprofile%\desktop\CloudUninstall"
CD "%userprofile%\desktop\CloudUninstall"
regedit /e regexport.txt "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
find "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall\" regexport.txt >> reg1.txt
set /a var=2
GOTO LOOPD
:LOOPD
FOR /F "skip=%var% tokens=* delims==" %%A in (reg1.txt) do set trans=%%A & GOTO WALKIT
PAUSE
:WALKIT
REM This transits the variable from the for /f loop into the current function
set current=%trans%
REM This then takes the REGEDIT string formatting and reformats it to standard text for new function
regedit /e %var%.txt "%current:~1,-2%"
find "DisplayName" %var%.txt >> %var%_a.txt
find "UninstallString" %var%.txt >> %var%_a.txt
set /a var=var+1
GOTO LOOPD
What I need is a way to compare a text file with names of programs against this set of files. Then, if the name from the text file appears in that list of files, export the uninstaller into a separate text file.

#echo off
rem Configure environment
setlocal enableextensions disabledelayedexpansion
rem Configure our "blacklist" file
set "blackList=%temp%\blacklist.txt"
rem To test, generate the blacklist file
(
echo Adobe Flash Player
echo Dell Touchpad
echo Nokia Suite
) > "%blacklist%"
echo.
type "%blacklist%"
echo.
rem From where to retrieve the information
set "key=HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall"
rem Variables used for temporary storage of values
set "displayName="
set "uninstallString="
rem Query the registry for the desired values and store values in variables. Each time a Uninstall key is found
rem output data. The complete list is being sent to a temporary file
(
for /f "tokens=1,2,*" %%a in ('reg query "%key%" /s ^| findstr /i /l /c:"%key%" /c:"DisplayName" /c:"UninstallString"') do (
if /i "%%a"=="DisplayName" (
set "displayName=%%c"
) else if /i "%%a"=="UninstallString" (
set "uninstallString=%%c"
) else (
if defined displayName if defined uninstallString (
setlocal enabledelayedexpansion
if not "!uninstallString:~0,1!!uninstallString:~0,1!"=="""" (
set "uninstallString="!uninstallString!"
set "uninstallString=!uninstallString:.exe=.exe" !"
)
echo(!displayName!^|!uninstallString!
endlocal
)
set "displayName="
set "uninstallString="
)
)
if defined displayName if defined uninstallString (
setlocal enabledelayedexpansion
echo(!displayName!=!uninstallString!
endlocal
)
) > "%temp%\ProgramList"
rem Compare the generated program list against black list
echo.
type "%temp%\ProgramList" | findstr /i /r /g:"%blacklist%"
echo.
rem Extract uninstallstring from list to another file
(for /f "tokens=1,* delims=^|" %%u in (
'findstr /i /r /g:"%blacklist%" ^< "%temp%\ProgramList"'
) do (
set "c=%%v"
echo(%%v
))>"%temp%\UninstallList"
echo.
type "%temp%\UninstallList"
echo.
endlocal
exit /b

Related

pass outer loop variable into nested loop

So my mission is to loop through a directory and set a variable to capture the zip file name.
then use that variable to parse what is on the left of the string before the underscore. That way I can name a log file. I searched high and low but I'm not seeing any good examples on Stack. when I use %%i it will return a full directory path. (which is not needed here.) If I use the %%z I get null back how can I pass my %zipfile% variable into my nested loop In()?
setlocal enableextensions enabledelayedexpansion
set dir1="C:\test\"
set 7zip="C:\Program Files\7-Zip\7z.exe"
set output="C:\test\Filelist.txt"
REM enter folder location
cd C:\test
REM loop through zip files
for /r %%i in (*.zip) do ( set zipfile=%%~nxi
for /F " delims=_" %%z in (%zipfile%) do (set log="%%z_file_list.txt")
)
Pause
REM Del %log%
Does the following help you out?
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "dir1=C:\test"
Set "7zip="%ProgramFiles%\7-Zip\7z.exe"
Set "output=C:\test\Filelist.txt"
For /F "Delims=" %%G In (
'Set "PATHEXT=" ^& %SystemRoot%\System32\where.exe /F /R "%dir1%" "?*_*.zip" 2^>NUL'
) Do (
For /F "Delims=_" %%H In (
"%%~nG"
) Do (
Echo Set "log=%%H_file_list.txt"
)
)
Pause

batch script how to create a string out of different variable parts

in my company we create software for different customers to handle our machines. As each product is unique, so is the control software, but not completely new. So for a start we copy an old project, rename it and change it until it fits.
Usually the directory name is the name for the new program (our ide uses the directory name, but also relies on some other files following the same name scheme).
For the renaming I've wrote a short batch script which finds the old name scheme and retrieves from the directory name the new one.
But the only solution I've found for this uses a new batchfile for each file to be renamed.
Is there a better way to get the content of !progNeu! ?
#echo off
SETLOCAL enabledelayedexpansion
set pfad=%CD%
for /d %%A in (%pfad%) do (set progNeu=%%~nxA)
for /f "tokens=1,2 delims=|" %%B in ('dir /b *.s19 ^| findstr /v "appl"') > do (
set progAlt=%%B
set rumpfAlt=!progAlt:.s19=!
>x ECHO !rumpfAlt!&FOR %%C IN (x) DO SET /A strlength=%%~zC - 2&del x
for %%D in (!rumpfAlt!*.*) do (
set progAlt=%%D
>x.bat echo #echo off
>>x.bat echo set ausg=!progAlt!
>>x.bat echo echo %%ausg:~!strlength!%%
for /f "" %%E in ('x.bat') do (
set "dateiNeu=!progNeu!%%E"
if exist !dateiNeu! del !dateiNeu!
rename %%D !dateiNeu!
)
del x.bat
)
)
If I have not missed something, this could be the equivalent to your code
#echo off
setlocal enableextensions disabledelayedexpansion
set "pfad=%CD%"
for /d %%A in ("%pfad%") do (
for /f "delims=" %%B in ('
dir /b *.s19 ^| findstr /v "appl"
') do for %%D in ("%%~nB*.*") do (
set "progAlt=%%D"
setlocal enabledelayedexpansion
for %%E in ("!progAlt:%%~nB=!") do (
endlocal
echo move /y "%%D" "%%~nxA%%~E"
)
)
)
I have removed almost all the inner variables that are simply using the values that the for replaceable parameters already hold, and used the adecuated modifiers to retrieve the needed part from the file names.

Moving files and renameing duplicats

I need to move files from C:\users\users name\documents\sound recordings\ directory to our network drive P:\transcription\users name\. I need the files to automatically get renamed if the file exist in the P:\transcription\users name directory. I am a novice and can only write simple batch files and the one I wrote to move the files will over write the files with the same name in the directory. Thanks
This may help.
It will display files to be moved with resulting filename. If it works ok for you , remove the line echo !src!%%~nxa - !dst!!file! and delete the rem keyword from rem move !src!%%a !dst!!file! >nul
#echo off
SetLocal EnableDelayedExpansion
set "wildcard=*.*" & rem files to search for
set "skipUsers=Guest Administrator" & rem users not to copy files
:: get users
set/a offset=0
for /F "skip=2 tokens=2 delims=," %%1 in ('wmic useraccount get name^,sid /format:csv') do (
set/a offset+=1, USER_MAX=offset
set "USER[!offset!]=%%1"
)
for /L %%i in (1,1,%USER_MAX%) do (
set/a skip=0, numFiles=0
set "currentUser=!USER[%%i]!"
set "src=C:\!currentUser!\documents\sound recordings\"
set "dst=P:\transcription\!currentUser!\"
rem get time stamp
for /f "tokens=2 delims==" %%A in ('wmic os get localdatetime /value') do set "Tm=%%A"
set "timeStamp=!Tm:~0,4!!Tm:~4,2!!Tm:~6,2!_!Tm:~8,2!!Tm:~10,2!!Tm:~12,2!"
for %%a in (%skipUsers%) do if /I "!currentUser!" equ "%%a" set/a skip=1
if !skip! neq 0 ( rem avoid copying blacklist users
echo !currentUser!: Skipping
) else (
<nul set/P="!currentUser!: Moving files"
pushd !src!
dir /ad !dst! >NUL 2>NUL || md !dst! & rem create destination folder if it doesn't exist
for %%a in (%wildcard%) do (
set "file=%%~nxa"
if exist "!dst!!file!" set "file=%%~na_!timeStamp!%%~xa" & rem rem if file exist, append a time stamp suffix to avoid overwriting
echo !src!%%~nxa - !dst!!file!
rem move !src!%%~nxa !dst!!file! >nul
set/a numFiles+=1
)
echo : !numfiles! files moved
popd
)
)
EndLocal
exit/B

How to scan a folder and store all file names in a array variable and then loop through the array?

I am new to batch and I am trying to do the following:
reading or scanning a folder
hold all file names in folder in an array variable (need to hold file name with or without extension)
loop through that array and create a call to a specific file/bat based on the type of file using an IF or CASE statement condition. example: if the filename has the word person in it, call a specific file/bat.
This is what I have so far:
#echo off
setlocal EnableDelayedExpansion
rem Populate the array with existent files in folder
set i=0
for %%b in (*.*) do (
set /A i+=1
set list[!i!]=%%b
)
set Filesx=%i%
rem Display array elements
for /L %%i in (1,1,%Filesx%) do echo !list[%%i]!
... do (
echo !list[%%i]! | find /i "person" >nul && call specific.bat !list[%%i]!
)
echo !list[%%i]! | find /i "person": find the word
>nul: disregard the output (we don't need it, just the errorlevel)
&&: if previous command was successful (the word was found), then...
Do you really need that array? You can do it "on the fly":
for %%b in (*.*) do (
echo %%b | find /i "person" >nul && call specific.bat "%%b"
)
for filename only, use %%~nb, for full name (including path), use %%~fb (see for /? for more options)
This a quick modified version from : Open a file through cmd and display the selected in specific editor
It will scan on your desktop for any batch files which contains the word : person
#ECHO OFF
Title Scan a folder and store all files names in an array variables
:MenuLoop
Cls & Color 0A
SETLOCAL
SET "ROOT=%userprofile%\Desktop\"
SET "EXT=*.bat"
SET "Count=0"
Set "Word2Search=Person"
SETLOCAL enabledelayedexpansion
REM Iterates throw the files on this current folder.
REM And Populate the array with existent files in folder
FOR /f "delims=" %%f IN ('dir /b /s "%ROOT%\%EXT%"') DO (
find /I "%Word2Search%" "%%f" >nul 2>&1 && (
SET /a "Count+=1"
set "list[!Count!]=%%~nxf"
set "listpath[!Count!]=%%~dpFf"
) || (
Call :Scanning
)
)
echo wscript.echo Len("%ROOT%"^) + 20 >"%tmp%\length.vbs"
for /f %%a in ('Cscript /nologo "%tmp%\length.vbs"') do ( set "cols=%%a")
If %cols% LSS 50 set /a cols=%cols% + 15
set Files=%Count%
set /a lines=%Count% + 10
Mode con cols=%cols% lines=%lines%
ECHO *******************************************************
ECHO Folder : "%ROOT%"
ECHO *******************************************************
echo(
rem Display array elements
for /L %%i in (1,1,%Files%) do echo [%%i] : !list[%%i]!
SET /a "COUNT_TOT=%Count%"
ECHO.
ECHO Total of [%EXT%] files(s) : %Count% file(s)
echo(
echo Type the number of what file did you want to edit ?
set /p "Input="
set "sublimeEXE=%programfiles%\Sublime Text 3\sublime_text.exe"
For /L %%i in (1,1,%Count%) Do (
If "%INPUT%" EQU "%%i" (
Rem Testing if sublime_text.exe exist to open with it the text file
If Exist "%sublimeEXE%" (
Start "Sublime" "%sublimeEXE%" "!listpath[%%i]!"
Rem Otherwise we open the text file with defalut application like notepad
) else (
Start "" Notepad.exe "!listpath[%%i]!"
)
)
)
EndLocal
Goto:MenuLoop
:Scanning
mode con cols=75 lines=3
Cls & Color 0A
echo(
echo Scanning in progress ...
goto :eof

Batch script that makes a numbered menu to view log files

I have recently started to learn how to make batch files. I have a folder that contains bunch of internet related log files. When I run the .cmd file (located in the same folder) I want it to be able to find out how many log files are in the folder and make a numbered menu from it. So lets say there are twenty files in the folder, then the user must be able to select from 1 to 21. 21 will close the batch file. Here is what I have done so far:
#echo off
setlocal enableextensions enabledelayedexpansion
set RawData1=TempData%random%.tmp
set FileCtr=0
:MAIN
dir *.log /b | findstr /i /n ".log" > %RawData1%
for /f "tokens=1 delims=:" %%a in (%RawData1%) do set FileCtr=%%a
set /a ExitCode=%FileCtr% + 1
set UserChoice=%ExitCode%
echo.
echo +++++++++++++++++++++++++++
echo Weblog File Viewer
echo +++++++++++++++++++++++++++
for /f "tokens=1-2 delims=:." %%a in (%RawData1%) do echo %%a. %%b
echo %Exitcode%. To Quit.
set /p UserChoice= Choose item number from menu (%UserChoice%):
echo\
echo user entered: %UserChoice%
pause
:THEEND
del /q %RawData1%
So what this batch file can do for now is that it figures out the number of log files and makes a numbered menu from it. Of course it won't show the filetype which is how I wanted it. So "Kelley-Blue-Book.log" for example is shown only as "Kelley-Blue-Book". However, if the user selects say number 4 from the list the program will terminate because I couldn't figure out how to make it actually open the desired log file using notepad.
This should do what you want:
#echo Off
setlocal EnableDelayedExpansion
set "Count=0"
pushd "%~dp0"
echo.
echo +++++++++++++++++++++++++++
echo Weblog File Viewer
echo +++++++++++++++++++++++++++
for %%A in (*.log) do (
set /a "Count+=1"
set "Menu[!Count!]=%%~fA"
set "Number= !Count!"
echo !Number:~-3!. %%~nA
)
set /a "Count+=1"
set "Number= %Count%"
echo %Number:~-3%. To Quit.
:Prompt
set "UserChoice="
set /p "UserChoice= Choose item number from menu (%Count%):"
if not defined UserChoice goto Prompt
set "UserChoice=%UserChoice:"=%"
if "%UserChoice%"=="%Count%" goto Done
for /f "tokens=1,* delims==" %%A in ('set Menu') do (
if /i "Menu[%UserChoice%]"=="%%~A" (
notepad "%%~fB"
set "UserChoice="
)
)
if defined UserChoice echo Invalid Choice.
goto Prompt
:Done
popd
endlocal
exit /b 0
Let me know if you want any explanations.
#echo off
setlocal enableextensions
set RawData1=TempData%random%.tmp
rem Get numbered list of files
dir /b "*.log" | findstr /i /n ".log" > %RawData1%
rem We could use 0 as exitCode,
rem but to keep original behaviour
rem lets count the number of files
for /F "tokens=*" %%f in ('type %RawData1% ^| find /c /v "" ') do set /A ExitCode=%%f + 1
if %ExitCode%==0 (
echo No log files
goto endProcess
)
rem show menu
for /f "tokens=1-2 delims=:." %%a in (%RawData1%) do echo %%a. %%b
echo %Exitcode%. To Quit.
set UserChoice=%ExitCode%
set /p UserChoice= Choose item number from menu (%UserChoice%):
if "%UserChoice%"=="" goto :EOF
if "%UserChoice%"=="%ExitCode%" goto endProcess
rem Search indicated file in list
set SelectedFile=
for /f "tokens=2 delims=:" %%f in ('findstr /B "%UserChoice%:" %RawData1%') do set SelectedFile=%%f
if "%SelectedFile%"=="" (
echo Incorrect selection
goto endProcess
)
if not exist %SelectedFile% (
echo File deleted
goto endProcess
)
notepad %SelectedFile%
:endProcess
del /q %RawData1%

Resources