I have a batch file that writes a line with an ip and a name for the ip in the etc/hosts file. Is there a way to check if this line already exists? Or alternatively just see if a word exists in the file?
edit:
want something like if string exists move on but if not echo
initial code
findstr "mystring" "C:\Windows\System32\drivers\etc\hosts" >nul 2>&1
if errorlevel 1 echo 111.222.333.444 mystring>>%systemroot%\SYSTEM32\DRIVERS\ETC\HOSTS
Solved: with suggested enhancements
findstr /V "^#" "C:\Windows\System32\drivers\etc\hosts" | findstr /ILC:"mystring" >nul 2>&1 ||^
(echo 111.222.333.444 mystring>>%systemroot%\SYSTEM32\DRIVERS\ETC\HOSTS)
can ignore commented out lines
can search for case-insensitive string
will write a string if string not found
I suggest following batch file code for this task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "HostsFile=%SystemRoot%\System32\drivers\etc\hosts"
if not "%ProgramFiles(x86)%" == "" if exist %SystemRoot%\Sysnative\cmd.exe set "HostsFile=%SystemRoot%\Sysnative\drivers\etc\hosts"
if not exist %HostsFile% goto AppendData
%SystemRoot%\System32\findstr.exe /I /L /C:"mystring" %HostsFile% >nul
if not errorlevel 1 goto EndBatch
%SystemRoot%\System32\findstr.exe /R /V "$" %HostsFile% >nul
if not errorlevel 1 echo/>>%HostsFile%
:AppendData
>>%HostsFile% echo 111.222.33.44 mystring
:EndBatch
endlocal
The third line defines the environment variable HostsFile with standard file path which is right on batch file being executed on 32-bit Windows by 32-bit cmd.exe or on 64-bit Windows by 64-bit cmd.exe in directory %SystemRoot%\System32.
The fourth line takes into account the Windows File System Redirector according to WOW64 Implementation Details. The batch file is executed on 64-bit Windows if there is defined an environment variable with name ProgramFiles(x86) with a non-empty value. But the batch file is executed by 32-bit cmd.exe in directory %SystemRoot%\SysWOW64 if there is %SystemRoot%\Sysnative\cmd.exe. The redirector Sysnative does not exist for 64-bit applications. In this case the file hosts must be referenced from within 32-bit environment on 64-bit Windows with using the Sysnative redirector in file path.
Next is checked if the file hosts exists at all. If the file does not exist, the data line to append can be directly written to the file without any further checks whereby the file hosts is created in this case.
Otherwise the command FINDSTR is used to search case-insensitive with a literally interpreted search string for mystring with redirecting the perhaps found line(s) to device NUL. FINDSTR exits with value 0 if there is at least one positive match and with value 1 if the searched string could not be found on any line.
if not errorlevel 1 means IF exit code is NOT GREATER OR EQUAL 1, or in other words LOWER THAN 1, or in this case EQUAL 0 because of FINDSTR never exits with a negative value as nearly all applications and commands. So if this condition is true, the file hosts contains at least once the searched string and nothing to change on file.
Otherwise FINDSTR is used once more to search this time with a regular expression for end of line and to output all lines not having a line ending because of option /V. So if last line in file hosts has no line ending, FINDSTR exits with value 0 because of having output one line with no line ending whereby this output is redirected to device NUL.
A line ending is appended to file hosts if FINDSTR exited with value 0 because of file hosts ends with no line ending before appending next the data line to add to this file.
The code above does not work if the batch file is not executed with elevated permissions of a local administrator or the file hosts has read-only attribute set or is otherwise protected against modification by a script.
BTW: An octet of an IPv4 address cannot be greater than 255. So 111.222.333.444 is a terrible example for an IPv4 address added to file hosts because of being an invalid IPv4 address.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
findstr /?
goto /?
if /?
set /?
setlocal /?
See also DosTips forum topic: ECHO. FAILS to give text or blank line - Instead use ECHO/
Related
Hello I am trying to rename all files ending with "VA.pdf" to "PA.pdf" using batch code
I tired this code but it is not working
REN *VA.pdf *PA.pdf
Appreciate any help
There can be used for this file renaming task:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
if exist "*!*VA.pdf" goto ExtendedVersion
setlocal EnableDelayedExpansion
for /F "eol=| delims=" %%I in ('dir *VA.pdf /A-D-L /B 2^>nul') do (
set "FileNamePDF=%%~nI"
set "FileNameNew=!FileNamePDF:~0,-2!PA%%~xI"
if not exist "!FileNameNew!" ren "!FileNamePDF!%%~xI" "!FileNameNew!"
)
endlocal
goto EndBatch
:ExtendedVersion
echo INFO: Extended version required because of a PDF file with exclamation marks.
for /F "eol=| delims=" %%I in ('dir *VA.pdf /A-D-L /B 2^>nul') do (
set "FileNamePDF=%%~nI"
setlocal EnableDelayedExpansion
set "FileNameNew=!FileNamePDF:~0,-2!PA%%~xI"
if not exist "!FileNameNew!" ren "!FileNamePDF!%%~xI" "!FileNameNew!"
endlocal
)
:EndBatch
endlocal
There is defined first the required execution environment with the first two command lines.
The IF condition in the third command line quickly checks if there is any PDF file with case-insensitive VA in the file name before the file extension .pdf containing one or more exclamation marks in the file name. The extended version of the processing loop is required if this condition is true.
The standard version enables first required delayed expansion. Then a FOR loop is used which runs in background with Windows installed into C:\Windows:
C:\Windows\System32\cmd.exe /c dir *VA.pdf /A-D-L /B 2>nul
The internal command DIR of cmd.exe searches
in the current directory as defined by the process starting cmd.exe for processing the batch file
for just file names because of option /A-D-L (attribute not directory and not link)
matching case-insensitive the wildcard pattern *VA.pdf in long or short 8.3 name
and outputs in bare format because of option /B just the file names with file extension, but without file path.
An error message output to handle STDERR (standard error) on DIR does not find any file system entry matching the criteria is suppressed by redirecting this error message to the device NUL.
Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line with using a separate command process started in background.
FOR respectively cmd.exe processing the batch file captures all output written to standard output stream of in background started cmd.exe and processes it line by line after started cmd.exe closed itself after finishing executing the command DIR.
FOR with option /F is used here to get a list of file names of *VA.pdf files loaded into memory of cmd.exe before really doing the file renames as otherwise it could happen especially on FAT drives (FAT32, exFAT) that some PDF files are skipped or processed more than once (on rename not possible).
FOR on using option /F ignores always empty lines which is no problem here as DIR with the used options does not output empty lines.
FOR would next split up the lines into substrings using horizontal tab and normal space as string delimiters, would look next if first tab/space separated string begins with a semicolon in which case it would also ignore the entire line for further processing, and would otherwise assign just the first tab/space separated string to the specified loop variable I before running the commands in body of FOR.
The default line splitting behavior is not wanted as PDF file names can contain one or more spaces. The usage of the option delims= defines an empty list of delimiters which turns off the line splitting behavior.
It is very unusual but nevertheless possible that a PDF file name begins with ; (semicolon). Such a file name should not be ignored by FOR. The option eol=| defines a vertical bar as end of line character which no file name can contain ever. Microsoft lists the characters not allowed in a file name on Windows file systems in the documentation about Naming Files, Paths, and Namespaces.
The current file name without file extension .pdf is assigned first to the environment variable FileNamePDF.
Next a string substitution is used to get from the string value of the environment variable FileNamePDF the file name without the last two characters VA concatenated with the string PA and the file extension .pdf assigned to the environment variable FileNameNew.
If there is not already a PDF file ending with PA in the file name before the file extension, there is next executed the command REN to rename the *VA.pdf file to *PA.pdf.
The command ENDLOCAL after the loop restores the previous environment before enabling delayed expansion and the command GOTO instructs the Windows Command Processor to continue processing the batch file with the command line below the label EndBatch which contains one more ENDLOCAL to restore the environment on starting the batch file processing.
The extended version is nearly the same as the standard version. The difference is that delayed variable expansion is not enabled on assigning the file name of the current VA.pdf file without the file extension to the environment variable FileNamePDF. That avoids interpreting the exclamation mark(s) in the file name as beginning/end of a delayed expanded variable reference resulting in a manipulation of the file name string before assigning it to the environment variable as it would happen with delayed expansion already enabled.
The extended version enables next delayed variable expansion inside the loop, does the same as the standard version and restores finally the previous environment before processing the next *VA.pdf file.
The extended version is slower because of the environment variables list copy and the other operations made in background by every execution of SETLOCAL as explained in full details in this answer. The command ENDLOCAL in the loop is required to avoid a stack overflow on processing lots of PDF files.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
ren /?
set /?
setlocal /?
In order to get the current Office installation path,
I set up this line
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WINWORD.EXE"
and the result is:
(Default) REG_SZ C:\PROGRA~1\MICROS~1\Office16\WINWORD.EXE
Path REG_SZ C:\Program Files\Microsoft Office\Office16\
useURL REG_SZ 1
SaveURL REG_SZ 1
How to grep out the "C:\Program Files\Microsoft Office\Office16\" in a variable?
Thanks.
By using the command line
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\winword.exe" /v Path
just the string value of Path is output which means on Windows XP:
! REG.EXE VERSION 3.0
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\winword.exe
Path REG_SZ C:\Program Files\Microsoft Office\Office16\
So this output starts with an empty line, a header of reg.exe version 3.0, one more empty line, the queried registry key and the queried registry value Path if found at all in Windows registry under specified key. There is a tab character between Path and REG_SZ and one more tab character between REG_SZ and the path string. The line with Path starts with four spaces.
On Windows Vista and later Windows versions the output is:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\winword.exe
Path REG_SZ C:\Program Files\Microsoft Office\Office16\
This output starts with an empty line like on Windows XP. But output is next already the queried registry key without any additional header. Last the line with queried registry value Path is output if found at all in Windows registry under specified key. The last line starts also with four spaces like on Windows XP. But there are four spaces between Path and REG_SZ and four spaces between REG_SZ and the path string instead of horizontal tabs.
This means for getting the path string using command FOR with option /F:
The first two lines of output of command REG can be always skipped.
It is necessary to check if third line contains already value Path or one more non empty line needs to be processed to have a batch file working also on Windows XP.
The last line has space or tab separated the strings Path, REG_SZ and the path string which could contain also 1 or more spaces or any other character allowed in a folder name.
The batch file code for this task:
#echo off
for /F "skip=2 tokens=1,2*" %%A in ('%SystemRoot%\System32\reg.exe query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\winword.exe" 2^>nul') do (
if /I "%%A" == "Path" if not "%%~C" == "" set "OfficePath=%%~C" & goto FoundPath
)
echo Could not determine MS Office path. MS Office is most likely not installed.
echo/
pause
goto :EOF
:FoundPath
rem Remove backslash at end of path if there is one at all.
if "%OfficePath:~-1%" == "\" set "OfficePath=%OfficePath:~0,-1%"
echo MS Office is installed in: "%OfficePath%"
rem Other command using environment variable OfficePath.
The command FOR executes in a background process started with cmd.exe /C the command line (with %SystemRoot% already expanded):
%SystemRoot%\System32\reg.exe query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\winword.exe" 2>nul
The output of this command process (= reg.exe) written to handle STDOUT is captured by FOR.
REG outputs to handle STDERR an error message if either the specified registry key or the specified registry value does not exist at all in Windows registry. This error output is redirected to device NUL to suppress it. Read the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded reg command line with using a separate command process started in background.
The command FOR could have nothing to process in case of registry key or registry value not found by REG resulting in execution of the command lines below the FOR loop informing the batch file user about this use case.
Otherwise command FOR skips because of skip=2 the first two captured lines which means on Windows Vista and later the first line processed by FOR is already the line containing Path. On Windows XP the third line being an empty line is ignored by FOR and the next line with queried registry key is processed next.
The line is split up because of tokens=1,2* and the default delimiters space/tab into 3 substrings.
On Windows Vista and later Windows:
Path is assigned to specified loop variable A.
REG_SZ is assigned to next loop variable B according to ASCII table.
C:\Program Files\Microsoft Office\Office16\ is assigned to loop variable C.This third string is not further split up on spaces/tabs because of *.
On Windows XP the first line tokenized by FOR results in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App being assigned to specified loop variable A and
Paths\winword.exe being assigned to next loop variable B.
Nothing is assigned to loop variable C because there is no more string on processed line.
A case-insensitive string comparison of value of loop variable A is made with fixed string Path to verify if FOR processed already the right line with Path value. On Windows Vista and later Windows versions this is already true on first line tokenized by FOR. On Windows XP this condition is first false and FOR processes therefore the next line now assigned the same strings to the loop variables A, B and C as on Windows Vista and later Windows versions.
On a true condition the path string assigned to loop variable C and not being an empty string is assigned to environment variable OfficePath with removing enclosing double quotes if the path string is enclosed at all in ". And next a jump is made to label FoundPath exiting the loop and continue batch file execution in code block on having the MS Office path.
In this code block first a backslash at end of path is removed if there is one at all to have assigned to environment variable OfficePath always the path string without a backslash at end independent on path string in registry not having or having a backslash at end using string substitution.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
for /?
goto /?
if /?
pause /?
reg /?
reg query /?
rem /?
set /?
From cmd.exe if you run reg query /? there is a specific switch that stands out.
/v Queries for a specific registry key values.
If omitted, all values for the key are queried.
When looking at your complete output, you are very specifically requiring the registry key value Path
So by Simply running:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WINWORD.EXE" /v Path
we get less noise to deal with.
With that logic, here is the batch which simply uses the : of the path string extracted as the delimiter and then joining %%a being C Drive, with %%b being rest of the path after : and we simply just join them again with the colon.
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2 delims=:" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WINWORD.EXE" /v Path') do (
set result=%%a
set result=!result:~-1!
set output=!result!:%%b
)
echo !output!
Just use the (javascript) regex .:(?!.*:).*
What this captures is:
.: - Drive letter
(?!.*:) - Not followed by other colons (illegal in Windows paths)
.* - Followed by the path
I am generating a Windows Batch script to copy a file, only when the source is updated. If the file is updated, I want to delete another file.
The problem is that I can't find a simple way to trigger an event when the file update happens.
I thought of using %ERRORLEVEL% but this gives 0 whether file is copied or not.
I also thought of saving the xcopy output to a text file and then processing the file but this just seems to a little impractical for such a simple task?
Any other Ideas?
Code so far
SET SOURCEFILE=%CD%\source.txt
SET DELFILE=%CD%\toDelete.txt
SET DESTDIR=%WINDIR%\Deployment\
xcopy "%SOURCEFILE%" "%DESTDIR%" /c /d /q /y
REM IF File is updated, delete %DELFILE%
I explain the method used in command line posted by Aacini on entire batch code:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceFile=source.txt"
set "DeleteFile=toDelete.txt"
set "DestinationDirectory=%SystemRoot%\Deployment\"
for /F %%I in ('%SystemRoot%\System32\xcopy.exe "%SourceFile%" "%DestinationDirectory%" /C /D /Q /Y 2^>nul') do set "CopiedFilesCount=%%I"
if %CopiedFilesCount% GTR 0 del "%DeleteFile%"
rem Add here more command lines using one of the 3 environment variables define above.
endlocal
First it is very important on copying a single file with XCOPY that the destination directory path ends with a backslash as otherwise XCOPY would prompt if the destination is a directory or a file.
XCOPY as used here always outputs to handle STDOUT as last line an information message with the number of files being copied at beginning even when nothing is copied or when an error occurred.
The command FOR executing XCOPY in a separate command process in background captures this output to handle STDOUT and processes it line by line.
Empty lines and lines starting with a semicolon are ignored with using the default options as used here with no eol= option. The other lines are processed with splitting each line up into strings separated by spaces or horizontal tabs on using default delimiters as used here because of no delims= option. Because of not using tokens= option just the first space/tab separated string of each line is assigned to loop variable I and the rest of the line is ignored.
The current value of the loop variable I is assigned on each processed line to environment variable CopiedFilesCount replacing its previous value.
The first space/tab separated string on last line output by XCOPY is the number of copied files which is here on copying just a single file either 0 or 1. So finally after FOR loop execution finished the environment variable CopiedFilesCount has either 0 or 1 as value.
The value is compared with GREATER THAN operator of command IF to determine if the file was copied in which case the other file is deleted.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
del /?
echo /?
endlocal /?
for /?
if /?
rem /?
set /?
setlocal /?
Ok, I've installed Dropbox but it didn't corresponded to what I was looking for so I uninstalled it with Revo Pro.
But, when i open the taskmanager there are still processes related to it running in my computer so I decided to make a batch to look out and delete all files that are related to it.
#echo off
cd c:\
:a
set /p a=Phrase that might be realted to it
for /r %%d IN (*.*) DO (
(
findstr /i /m /c:%a% "%%d"
if "%errorlevel%"=="0" del "%%d"
echo %errorlevel%
)
)
pause
The problem is: when I run findstr using loop even when there is no match for my variable "%a%" in an analized file %errorlevel% returns as 0. But when I use findstr alone and there isn't a match %ERRORLEVEL% returns as 1 and 0 for a match.
If I use it, I'll delete all my PC files haha. What's wrong with the code?
Within a parenthesised series of statements, any %var% is replaced by the value of that variable at the time the verb controlling that statement-sequence (or block) is encountered.
Here, the block is the entire sequence of statements controlled by the for. %errorlevel% is replaced by the status of errorlevel at the time the for is encountered, so probably 0.
If you use
findstr /i /m /c:%a% "%%d"
if not errorlevel 1 del "%%d"
echo %errorlevel%
then the run-time value of errorlevel is used (ie. as it changes through the operation of the loop) and the command means "if errorlevel is not (1 or greater than 1) do this..."
The findstr will set errorlevel to 0 on found, 1 on not found and 2 for file not found(IIRC) so NOT (1 or greater than 1) selects 0 only. Note that in certain esoteric circumstances, errorlevel may become negative, but after a findstr I believe 0..2 is the allowed range.
Not sure what's wrong with the code, but you can probably skip it using the && operand.
findstr /i /m /c:%a% "%%d" && del "%%d" echo %errorlevel%
Thanks to Stephan for correcting the example.
Whenever Windows command interpreter encounters ( being interpreted as begin of a command block, it parses the entire command block up to matching ) marking end of the command block and replaces all %variable% by current value of the variable.
This means in this case that before command FOR is the first time executed, everything from ( after DO up to last ) is processed already with replacing all %variable% references by current value of the appropriate variable. Then the already preprocessed block is executed one (on command IF) or more times (on command FOR).
This behavior can be seen by debugging the batch file. For debugging a batch file first #echo off must be removed or commented out with command REM or changed to #echo on. Then a command prompt window must be opened and the batch file is executed from within this command prompt window by typing its name with full path enclosed in double quotes if path or name contains a space character. The Windows command interpreter shows now all command lines and command blocks after preprocessing before executing and of course the standard messages and the error messages output by the commands or by Windows command interpreter itself in case of a syntax error in batch file.
Opening a command prompt window means running cmd.exe with option /K to Keep window open after execution of a command or a batch script. Double clicking on a batch file starts also cmd.exe for processing the batch file, but with parameter /C to Close the window automatically after batch processing terminated independent on cause - successful finished or an error occurred.
The command prompt window opened before running the batch file remains open after batch processing finished successfully or with an error except the batch file contains command EXIT without parameter /B. So experts in batch code writing test batch files always by running them from within a command prompt window instead of double clicking on them.
Delayed variable expansion is needed for variables set or modified and referenced within same command block as explained by help of command SET output on running in a command prompt window set /?.
#echo off
setlocal EnableDelayedExpansion
cd /D C:\
:a
set /P "a=Phrase that might be realted to it: "
for /r %%d in (*) do (
%SystemRoot%\System32\findstr.exe /i /m /c:"%a%" "%%d"
if "!errorlevel!" == "0" del "%%d" >nul
)
endlocal
But for checking the exit code of a previous command there is also if errorlevel syntax as explained by Microsoft in support article Testing for a Specific Error Level in Batch Files.
#echo off
setlocal EnableDelayedExpansion
cd /D C:\
:a
set /P "a=Phrase that might be realted to it: "
for /r %%d in (*) do (
%SystemRoot%\System32\findstr.exe /i /m /c:"%a%" "%%d" >nul
if not errorlevel 1 del "%%d" >nul
)
endlocal
if errorlevel X tests if exit code of previous command or application when it modifies the errorlevel variable at all is greater or equal X. By using if not errorlevel X the check is if last exit code is lower than X which is here a test if exit code is 0.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cd /?
del /?
echo /?
for /?
if /?
set /?
And see also
Microsoft's command-line reference
SS64.com - A-Z index of the Windows CMD command line
Microsoft article about Using command redirection operators
Answer on question Single line with multiple commands using Windows batch file
How to set environment variables with spaces?
I have written the following .bat file, and it runs perfectly on my Windows 2000 machine, but will not run on my Windows 7 or Windows XP machines. Basically it just loops through the current directory and runs a checksum program which returns the checksum. The output of the program is saved to a text file and then formatted to remove the checksum of the output file.
#Echo Off
for /r %%f in (*.txt) do crc32sum.exe %%f >> all_checksums.txt
ren all_checksums.txt old.txt
findstr /v /e /c:"all_checksums.txt" old.txt > all_checksums.txt
del old.txt
When I run this file on my Win2k PC with a bunch of text files and the crc32sum.exe in a folder, it outputs the file. On other machines it outputs a blank file. I turned Echo on and kept only the for loop line and found that the output from executing the crc32sum.exe is nothing. If you manually run the crc32sum.exe file it outputs the checksum no problem.
Any ideas as to how to fix this?
EDIT: Here is a link to the software: http://www.di-mgt.com.au/src/digsum-1.0.1.zip
EDIT2: New development, it seems that the file works if the path of the folder has no spaces in it i.e. C:\temp or C:\inetpub\ftproot or C:\users\admin\Desktop\temp. Does anyone know how I can make this work with paths that have spaces? %%~f doesnt work it says unexpected.
Try this modified batch code which worked on Windows XP SP3 x86:
#echo off
goto CheckOutput
rem Command DEL does not terminate with an exit code greater 0
rem if the deletion of a file failed. Therefore the output to
rem stderr must be evaluated to find out if deletion was
rem successful or (for a single file) the file existence is
rem checked once again. For details read on Stack Overflow
rem the answer http://stackoverflow.com/a/33403497/3074564
rem The deletion of the file was successful if file created
rem from output message has size 0 and therefore the temp
rem file can be deleted and calculation of the CRC32 sums
rem can be started.
:DeleteOutput
del /F "all_checksums.txt" >nul 2>"%TEMP%\DelErrorMessage.tmp"
for %%E in ("%TEMP%\DelErrorMessage.tmp") do set "FileSize=%%~zE"
if "%FileSize%" == "0" (
set "FileSize="
del "%TEMP%\DelErrorMessage.tmp"
goto CalcCRC32
)
set "FileSize="
echo %~nx0: Failed to delete file %CD%\all_checksums.txt
echo.
type "%TEMP%\DelErrorMessage.tmp"
del "%TEMP%\DelErrorMessage.tmp"
echo.
echo Is this file opened in an application?
echo.
set "Retry=N"
set /P "Retry=Retry (N/Y)? "
if /I "%Retry%" == "Y" (
set "Retry="
cls
goto CheckOutput
)
set "Retry="
goto :EOF
:CheckOutput
if exist "all_checksums.txt" goto DeleteOutput
:CalcCRC32
for /R %%F in (*.txt) do (
if /I not "%%F" == "%CD%\all_checksums.txt" (
crc32sum.exe "%%F" >>"all_checksums.txt"
)
)
The output file in current directory is deleted if already existing from a previous run. Extra code is added to verify if deletion was successful and informing the user about a failed deletion with giving the user the possibility to retry after closing the file in an application if that is the reason why deletion failed.
The FOR command searches because of option /R recursive in current directory and all its subdirectories for files with extension txt. The name of each found file with full path always without double quotes is hold in loop variable F for any text file found in current directory or any subdirectory.
The CRC32 sum is calculated by 32-bit console application crc32sum in current directory for all text files found with the exception of the output file all_checksums.txt in current directory. The output of this small application is redirected into file all_checksums.txt with appending the single output line to this file.
It is necessary to enclose the file name with path in double quotes because even with no *.txt file containing a space character or one of the special characters &()[]{}^=;!'+,`~ in its name, the path of the file could contain a space or one of those characters.
For the files
C:\Temp\test 1.txt
C:\Temp\test 2.txt
C:\Temp\test_3.txt
C:\Temp\TEST\123-9.txt
C:\Temp\TEST\abc.txt
C:\Temp\TEST\hello.txt
C:\Temp\TEST\hellon.txt
C:\Temp\Test x\test4.txt
C:\Temp\Test x\test5.txt
the file C:\Temp\all_checksums.txt contains after batch execution:
f44271ac *test 1.txt
624cbdf9 *test 2.txt
7ce469eb *test_3.txt
cbf43926 *123-9.txt
352441c2 *abc.txt
0d4a1185 *hello.txt
38e6c41a *hellon.txt
1b4289fa *test4.txt
f44271ac *test5.txt
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
cls /?
del /?
echo /?
for /?
goto /?
if /?
rem /?
set /?
type /?
One of the help pages output on running for /? informs about %~I, %~fI, %~dI, %~pI, %~nI, %~xI, %~sI, %~aI, %~tI, %~zI.
Using in a batch file f (in lower case) as loop variable and referencing it with %%~f is a syntax error as command processor expects next the loop variable. %%~ff would be right, but could be different to %%~fI (name of a file/folder with full path and extension without quotes) in comparison to %%~I (string without surrounding quotes).
It is not advisable to use (those) small letters as loop variable. It is better to use upper case letters or character # as loop variable. The loop variable and also those modifiers are case sensitive while nearly everything else in a batch file is case insensitive.