move tiff/tif files having a hyphen in the name - batch-file

I have a batch file which moves .tiff/tif files from one folder to another if the filename has digits, for example,
0000002341567.tif. It is working fine but
my requirement is to move file even if it has a name like 000000234156-7 or 0000002341567-s
So to say the file name can be suffixed with - and a one digit number or a hyphen and a character.
for %%I in ("C:\Documents\Pictures\*.tif*") do (
if !FileCount! EQU 0 (
echo Exiting after having moved already %FileCount% TIF files.
goto LoopEnd
)
set "HasOnlyDigits=1"
for /F "tokens=1 delims=0123456789" %%T in ("%%~nI") do set "HasOnlyDigits=%%T"
if "!HasOnlyDigits!" == "1" (
move /Y "%%I" "%FolderGood%"
)

findstr has a very limited set of REGEX, but it is enough for this task:
#echo off
set filecount=1
setlocal enabledelayedexpansion
for %%I in ("*.tif*") do (
if !FileCount! EQU 0 (
echo Exiting after having moved already %FileCount% TIF files.
goto LoopEnd
)
echo %%~nI|findstr /R "^[0-9][0-9]*-.$" >nul && (
echo yes %%I
ECHO move /Y "%%I" "%FolderGood%"
set filecount+=1
) || (
echo no %%I
)
)
:loopend
The REGEX here consists of:
^ Start of the line (string)
[0-9] Any digit
[0-9]* any digit (zero or any nunmber of any digit) (previous [0-9] to ensure, there is minimum one digit)
- a dash
. any character
$ End of the line (string)

Related

Batch script programmimng: save line value from a txt file into a variable [duplicate]

This question already has an answer here:
Variables are not behaving as expected
(1 answer)
Closed 3 years ago.
I want to read a text file where every line has a number. Negative numbers need to be replaced by 0 and written to a new file along with the rest of the positive numbers.
The problem is that I want to save the value of a line, i.e. %%a into a new variable. Then I'll check if the first character of that variable is '-' if so, I'll set the value to 0 for that line in the final file if not, it will remain as is.
But I cannot save the line value into anything. Below is my code.
3.txt is the original file, tempfile.txt is the final file.
set filem=3.txt
set tempfile=tempfile.txt
for /f "tokens=*" %%a in (%filem%) do (
set linevalue=%%a
IF %linevalue:~0,1% EQU - (
echo 0>>%tempfile%
) ELSE (
echo %%a>>%tempfile%
)
)
pause
If your numbers are really integers, you could give the following method a try:
#Echo Off
Set "filem=3.txt"
Set "tempfile=tempfile.txt"
If Exist "%filem%" (
( For /F "Tokens=1* Delims=]" %%G In (
'""%__AppDir__%find.exe" /N /V ""<"%filem%""'
) Do If "%%H" == "" (
Echo=%%H
) Else (
If %%H Lss 0 (
Echo 0
) Else Echo %%H
)
)>"%tempfile%"
)
Pause
If they're floating point numbers, you'd be both setting and using variables within the same code block, so you would need to use delayed expansion, (which was missing from your code):
#Echo Off
SetLocal DisableDelayedExpansion
Set "filem=3.txt"
Set "tempfile=tempfile.txt"
If Exist "%filem%" (
( For /F "Tokens=1* Delims=]" %%G In (
'""%__AppDir__%find.exe" /N /V ""<"%filem%""'
) Do If "%%H" == "" (
Echo=%%H
) Else (
Set "LineVal=%%H"
SetLocal EnableDelayedExpansion
If "!LineVal:~,1!" == "-" (
Echo 0
) Else Echo %%H
EndLocal
)
)>"%tempfile%"
)
Pause
I am assuming that you will run the bat/cmd in the same directory/folder as your code files, otherwise, edit the cd /d "%~dp0" adding the full/complete folder of your files.
#echo off
cd /d "%~dp0"
set "filem=.\3.txt"
type nul >".\tempfile.txt"
set "tempfile=.\tempfile.txt"
for /f "tokens=1*" %%a in ('type "%filem%"')do (
echo["%%~a"|%__APPDIR__%findstr.exe \-[0-9] >nul && (
echo[0>>"%tempfile%" ) || ( echo/%%~a%%b>>"%tempfile%" )
)
goto :EOF

Verifying MD5 hashes in Batch?

I am writing a batch file and I need it to verify a file's MD5 hash before continuing on with the script. For example:
#echo off
if MD5 equ 79054025255fb1a26e4bc422aef54eb4 (
echo MD5 identical!
) else (
echo MD5 does not match.
)
Thanks!
The standard Windows utility CERTUTIL can be used to generate MD5 (and other) hashes.
For example:
certutil -hashfile yourFile MD5
However, the output (versions prior to Windows 10) will not be formatted as a single string of contiguous hex digits.
npocmaka used CERTUTIL in his batch utility to generate a single MD5 string.
In a similar manner, I also used CERTUTIL with my utility: HASHSUM.BAT - a batch file emulation of unix utilities like md5sum, shasum, etc.
HASHSUM.BAT does more than compute MD5 for a single file, but it is also convenient to use for what you want.
For example:
echo 79054025255fb1a26e4bc422aef54eb4 yourFileName | hashsum /c /ns
REM - There must be exactly two spaces between the MD5 hash and the filename
Will yield output like
---------- <stdin> ----------
OK: yourFileName
or
---------- <stdin> ----------
*FAILED: yourFileName
Or you can take total control of the output
echo 79054025255fb1a26e4bc422aef54eb4 yourFileName | hashsum /c /q && (
echo MD5 identical!
) || (
echo MD5 does not match.
)
Or, if you really wanted, you could capture the MD5 value and do the comparison yourself:
for /f %%N in ('hashsum /a md5 yourFileName') do set "MD5=%%N"
if %MD5% equ 79054025255fb1a26e4bc422aef54eb4 (
echo MD5 identical!
) else (
echo MD5 does not match.
)
I'm posting the code for the current version 1.4 of HASHSUM.BAT, but I don't promise to keep this code up-to-date. I recommend you get the code from the DOSTIPS site where I originally posted it. There you can also see a more thorough discussion of all the HASHSUM.BAT capabilities, as well as some more examples of usage.
#if (#X)==(#Y) #end /* Harmless hybrid line that begins a JScript comment
#goto :Batch
::::HASHNUM.BAT history
::::
:::: v1.4 2016-12-26 - Convert /A value to upper case because some Windows
:::: versions are case sensitive. Also improve JScript file
:::: read performance by reading 1000000 bytes instead of 1.
:::: v1.3 2016-12-17 - Bug fixes: Eliminate unwanted \r\n from temp file by
:::: reading stdin with JScript instead of FINDSTR.
:::: Fix help to ignore history.
:::: v1.2 2016-12-07 - Bug fixes: Exclude FORFILES directories and
:::: correct setlocal/endlocal management in :getOptions
:::: v1.1 2016-12-06 - New /V option, and minor bug fixes.
:::: v1.0 2016-12-05 - Original release
:::
:::HASHSUM [/Option [Value]]... [File]...
:::
::: Print or check file hashes using any of the following standard
::: hash algorithms: MD5, SHA1, SHA256, SHA384, or SHA512.
:::
::: HASHSUM always does a binary read - \r\n is never converted to \n.
:::
::: In the absence of /C, HASHSUM computes the hash for each File, and writes
::: a manifest of the results. Each line of output consists of the hash value,
::: followed by a space and an asterisk, followed by the File name. The default
::: hash alogrithm is sha256. File may include wildcards, but must not contain
::: any path information.
:::
::: If File is not given, then read from standard input and write the hash
::: value only, without the trailing space, asterisk, or file name.
:::
::: Options:
:::
::: /? - Prints this help information to standard output.
:::
::: /?? - Prints paged help using MORE.
:::
::: /V - Prints the HASHNUM.BAT version.
:::
::: /A Algorithm
:::
::: Specifies one of the following hash algorithms:
::: MD5, SHA1, SHA256, SHA384, SHA512
:::
::: /P RootPath
:::
::: Specifies the root path for operations.
::: The default is the current directory.
:::
::: /S - Recurse into all Subdirectories. The relative path from the root
::: is included in the file name output.
::: This option is ignored if used with /C.
:::
::: /I - Include the RootPath in the file name output.
::: This option is ignored if used with /C.
:::
::: /T - Writes a space before each file name, rather than an
::: asterisk. However, files are still read in binary mode.
::: This option is ignored if used with /C.
:::
::: /C - Read hash values and file names from File (the manifest), and verify
::: that local files match. File may include path information with /C.
:::
::: If File is not given, then read hash and file names from standard
::: input. Each line of input must have a hash, followed by two spaces,
::: or a space and an asterisk, followed by a file name.
:::
::: If /A is not specified, then the algorithm is determined by the
::: File extension. If the extension is not a valid algorithm, then
::: the algorithm is derived based on the length of the first hash
::: within File.
:::
::: Returns ERRORLEVEL 1 if any manifest File is not found or is invalid,
::: or if any local file is missing or does not match the hash value in
::: the manifest. If all files are found and match, then returns 0.
:::
::: /NE - (No Errors) Suppresses error messages when using /C.
:::
::: /NM - (No Matches) Suppresses listing of matching files when using /C.
:::
::: /NS - (No Summary) Suppresses summary information when using /C.
:::
::: /Q - (Quiet) Suppresses all output when using /C.
:::
:::HASHSUM.BAT version 1.4 was written by Dave Benham
:::maintained at http://www.dostips.com/forum/viewtopic.php?f=3&t=7592
============= :Batch portion ===========
#echo off
setlocal disableDelayedExpansion
:: Define options
set "options= /A:"" /C: /I: /P:"" /S: /T: /?: /??: /NE: /NM: /NS: /Q: /V: "
:: Set default option values
for %%O in (%options%) do for /f "tokens=1,* delims=:" %%A in ("%%O") do set "%%A=%%~B"
set "/?="
:getOptions
if not "%~1"=="" (
set "test=%~1"
setlocal enableDelayedExpansion
if "!test:~0,1!" neq "/" endlocal & goto :endOptions
set "test=!options:*%~1:=! "
if "!test!"=="!options! " (
endlocal
>&2 echo Invalid option %~1
exit /b 1
) else if "!test:~0,1!"==" " (
endlocal
set "%~1=1"
) else (
endlocal
set "%~1=%~2"
shift /1
)
shift /1
goto :getOptions
)
:endOptions
:: Display paged help
if defined /?? (
(for /f "delims=: tokens=*" %%A in ('findstr "^:::[^:] ^:::$" "%~f0"') do #echo(%%A)|more /e
exit /b 0
) 2>nul
:: Display help
if defined /? (
for /f "delims=: tokens=*" %%A in ('findstr "^:::[^:] ^:::$" "%~f0"') do echo(%%A
exit /b 0
)
:: Display version
if defined /v (
for /f "delims=: tokens=*" %%A in ('findstr /ric:"^:::%~nx0 version" "%~f0"') do echo(%%A
exit /b 0
)
:: If no file specified, then read stdin and write to a temp file
set "tempFile="
if "%~1" equ "" set "tempFile=%~nx0.%time::=_%.%random%.tmp"
if defined tempFile cscript //nologo //E:JScript "%~f0" "%temp%\%tempFile%"
if defined /P cd /d "%/P%" || exit /b 1
if defined /C goto :check
:generate
if defined tempFile cd /d "%temp%"
if not defined /A set "/A=sha256"
if defined /S set "/S=/s"
if defined /T (set "/T= ") else set "/T=*"
call :defineEmpty
if not defined /P goto :generateLoop
if not defined /I goto :generateLoop
if "%/P:~-1%" equ "\" (set "/I=%/P:\=/%") else set "/I=%/P:\=/%/"
set "rtn=0"
:generateLoop
(
for /f "delims=" %%F in (
'forfiles %/s% /m "%tempFile%%~1" /c "cmd /c if #isdir==FALSE echo #relpath" 2^>nul'
) do for /f "delims=" %%A in (
'certutil.exe -hashfile %%F %/A% ^| find /v ":" ^|^| if %%~zF gtr 0 (echo X^) else echo %empty%'
) do (
set "file=%%~F"
set "hash=%%A"
setlocal enableDelayedExpansion
set "file=!file:~2!"
if defined tempFile (
if !hash! equ X (
set "rtn=1"
echo ERROR
) else echo !hash: =!
) else (
if !hash! equ X (
set "rtn=1"
echo ERROR: !/I!!file!
) else echo !hash: =! !/T!!/I!!file:\=/!
)
endlocal
)
) || (
set "rtn=1"
echo MISSING: %/T%%1
)
shift /1
if "%~1" neq "" goto :generateLoop
if defined tempFile del "%tempFile%"
exit /b %rtn%
:check
if defined /Q for %%V in (/NE /NM /NS) do set "%%V=1"
set /a manifestCnt=missingManifestCnt=invalidCnt=missingCnt=failCnt=okCnt=0
:checkLoop
set "alogorithm=%/A%"
if defined tempFile set "tempFile=%temp%\%tempFile%"
for %%F in ("%tempFile%%~1") do call :checkFile "%%~F"
if defined tempFile del "%tempFile%"
shift /1
if "%~1" neq "" goto :checkLoop
if not defined /NS (
echo ========== SUMMARY ==========
echo Total manifests = %manifestCnt%
echo Matched files = %okCnt%
echo(
if %missingManifestCnt% gtr 0 echo Missing manifests = %missingManifestCnt%
if %invalidCnt% gtr 0 echo Invalid manifests = %invalidCnt%
if %missingCnt% gtr 0 echo Missing files = %missingCnt%
if %failCnt% gtr 0 echo Failed files = %failCnt%
)
set /a "1/(missingManifestCnt+invalidCnt+missingCnt+failCnt)" 2>nul && (
echo(
exit /b 1
)
exit /b 0
:checkFile
set /a manifestCnt+=1
if not defined /Q if defined tempfile (echo ---------- ^<stdin^> ----------) else echo ---------- %1 ----------
if not defined algorithm set "/A="
set "src=%~1"
if not defined /A echo *.md5*.sha1*.sha256*.sha384*.sha512*|find /i "*%~x1*" >nul && for /f "delims=." %%A in ("%~x1") do set "/A=%%A"
findstr /virc:"^[0123456789abcdef][0123456789abcdef]* [ *][^ *?|<>]" %1 >nul 2>nul && (
if not defined /NE if defined tempFile (echo *INVALID: ^<stdin^>) else echo *INVALID: %1
set /a invalidCnt+=1
exit /b
)
(
for /f "usebackq tokens=1* delims=* " %%A in (%1) do (
set "hash0=%%A"
set "file=%%B"
if defined /A (call :defineEmpty) else call :determineFormat
setlocal enableDelayedExpansion
set "file=!file:/=\!"
for /f "tokens=1* delims=" %%C in (
'certutil.exe -hashfile "!file!" !/A! ^| find /v ":" ^|^| if exist "!file!" (echo !empty!^) else echo X'
) do set "hash=%%C"
if /i "!hash0!" equ "!hash: =!" (
if not defined /NM echo OK: !file!
endlocal
set /a okCnt+=1
) else if !hash! equ X (
if not defined /NE echo *MISSING: !file!
endlocal
set /a missingCnt+=1
) else (
if not defined /NE echo *FAILED: !file!
endlocal
set /a failCnt+=1
)
)
) 2>nul || (
if not defined /NE echo *MISSING: %1
set /a missingManifestCnt+=1
)
exit /b
:determineFormat
if "%hash0:~127%" neq "" (
set "/A=SHA512"
) else if "%hash0:~95%" neq "" (
set "/A=SHA384"
) else if "%hash0:~63%" neq "" (
set "/A=SHA256"
) else if "%hash0:~39%" neq "" (
set "/A=SHA1"
) else set "/A=MD5"
:defineEmpty
if /i "%/A%"=="md5" (
set "empty=d41d8cd98f00b204e9800998ecf8427e"
set "/A=MD5"
) else if /i "%/A%"=="sha1" (
set "empty=da39a3ee5e6b4b0d3255bfef95601890afd80709"
set "/A=SHA1"
) else if /i "%/A%"=="sha256" (
set "empty=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
set "/A=SHA256"
) else if /i "%/A%"=="sha384" (
set "empty=38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b"
set "/A=SHA384"
) else if /i "%/A%"=="sha512" (
set "empty=cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"
set "/A=SHA512"
) else (
echo ERROR: Invalid /A algorithm>&2
(goto) 2>nul&exit /b 1
)
exit /b
************* JScript portion **********/
var fso = new ActiveXObject("Scripting.FileSystemObject");
var out = fso.OpenTextFile(WScript.Arguments(0),2,true);
var chr;
while( !WScript.StdIn.AtEndOfStream ) {
chr=WScript.StdIn.Read(1000000);
out.Write(chr);
}
try with MD5.BAT :
set "file=c:\myfile.ext"
call md5.bat "%file%" md5
if "%md5%" equ "79054025255fb1a26e4bc422aef54eb4" (
echo MD5 identical!
) else (
echo MD5 does not match.
)

findstr multiple search string and print each occurrence only the first line

for example i have text file with content
superman
batman
hello world
sport cars
hello world2
jackie chan
flower
supermom
hello world3
clock
fried chicken
microsoft
flower boy
flash dance
flower girl
flowerwoman
sun flower
what the hello
i want to create a batch file using findstr with multiple search string, for example: hello and flower, but i want to print only the first occurence each, in other words, it will skip the first search string and move on to search the next string. so the result will be like this:
hello world
flower
hello world3
flower boy
what the hello
is this possible? i can print all the occurence found in multiple files to output.txt with this code
#echo off
>"output.txt" (
for %%F in (*.txt) do (
findstr /c:"hello" /c:"flower" "%%F"
(echo()
)
)
findstr . "output.txt" >"output.txt.new"
move /y "output.txt.new" "output.txt" >nul
type output.txt
#echo off
setlocal EnableDelayedExpansion
set "word[0]=hello"
set "word[1]=flower"
set "lastFind="
>"output.tmp" (
for %%F in (*.txt) do (
for /F "delims=" %%a in ('findstr /c:"%word[0]%" /c:"%word[1]%" "%%F"') do (
set "line=%%a"
if not defined lastFind (
if "!line:%word[0]%=!" equ "!line!" (set lastFind=0) else set lastFind=1
)
for %%b in (!lastFind!) do for /F %%c in ("!word[%%b]!") do if "!line:%%c=!" equ "!line!" (
echo !line!
set /A "lastFind=(lastFind+1)%%2"
)
)
rem Activate next line to restart the seek in each file
REM set "lastFind="
)
)
ren output.tmp output.txt
type output.txt
#echo off
setlocal enableDelayedExpansion
set "MATCH1=hello"
set "MATCH2=flower"
>"output.txt" (
for %%F in (*.txt) do if not %%~nxF==output.txt (
set matchIndex=0
set expectedMatch=%MATCH1%
for /f "delims=" %%a in ('findstr /c:"%MATCH1%" /c:"%MATCH2%" "%%F"') do (
echo %%a | find "!expectedMatch!" >nul
if !matchIndex!==0 (
set matchIndex=1
if errorlevel 1 set matchIndex=2 & ver>nul
)
if not errorlevel 1 (
echo %%a
set /a matchIndex=!matchIndex! %% 2 + 1
call set "expectedMatch=%%MATCH!matchIndex!%%"
)
)
)
)
type output.txt
pause
Currently the expected match index is reset to the first search string each new *.txt file, so in case you want a continuous alteration of strings between files simply move set matchIndex=1 before the first loop.

Split string in batch file

I am new to using batch files so could someone please help me split a string i am getting from a file.
I am using %USERPROFILE% to get my string.
The string is: "C:\Users\nicholas"
I would like to keep the C:\ part, but get rid of the \Users\nicholas part.
for /f "tokens=2 delims=\" %A in ('set userprofile') do echo %A\
See for /?
Also
echo %userprofile:~0,3%
If you carefully read the output of set /?, you'll find the answer:
May also specify substrings for an expansion.
%PATH:~10,5%
would expand the PATH environment variable, and then use only the 5
characters that begin at the 11th (offset 10) character of the expanded
result.
So, you can use something like this to get the first 3 characters of your string:
> echo %userprofile:~0,3%
C:\
I As you need the drive where where the users are located you can use directly
%systemdrive% variable - this is the drive where the windows is installed
II the easiest way to get a drive from path:
for %%a in ("%userprofile%") do echo %%~da\
%~da - expands a path to its drive only
III over-complicated but powerful way (split function that can be used for a different things):
#echo off
call :split "%userprofile%" "\" 1 drive
echo %drive%\
goto :eof
:split [%1 - string to be splitted;%2 - split by;%3 - possition to get; %4 - if defined will store the result in variable with same name]
::http://ss64.org/viewtopic.php?id=1687
setlocal EnableDelayedExpansion
set "string=%~2%~1"
set "splitter=%~2"
set /a position=%~3
set LF=^
rem ** Two empty lines are required
echo off
for %%L in ("!LF!") DO (
for /f "delims=" %%R in ("!splitter!") do (
set "var=!string:%%~R%%~R=%%~L!"
set "var=!var:%%~R=%%~L!"
if "!var!" EQU "!string!" (
echo "%~1" does not contain "!splitter!" >&2
exit /B 1
)
)
)
if "!var!" equ "" (
endlocal & if "%~4" NEQ "" ( set "%~4=")
)
if !position! LEQ 0 ( set "_skip=" ) else (set "_skip=skip=%position%")
for /f "eol= %_skip% delims=" %%P in (""!var!"") DO (
if "%%~P" neq "" (
set "part=%%~P"
goto :end_for
)
)
set "part="
:end_for
if not defined part (
endlocal
echo Index Out Of Bound >&2
exit /B 2
)
endlocal & if "%~4" NEQ "" (set %~4=%part%) else echo %part%
exit /b 0

How to check a string does not start with a number in Batch?

How can I check that the first character of a string is a letter and so that it is not a number, or rather a cipher? There are no spaces or special characters in this string.
#ECHO OFF
SETLOCAL
SET /a num=5678
CALL :initnum
SET "num=hello"
CALL :initnum
SET "num=4ello"
CALL :initnum
SET "num=hell0"
CALL :initnum
SET "num=he8lo"
CALL :initnum
SET "num="
CALL :initnum
ECHO(==============
SET /a nam=7654
SET "nem=hello"
SET "nim=4ello"
SET "nom=hell0"
SET "num=he8lo"
SET "nzm="
CALL :initnum2 nam
CALL :initnum2 nem
CALL :initnum2 nim
CALL :initnum2 nom
CALL :initnum2 num
CALL :initnum2 nzm
GOTO :EOF
:initnum
IF NOT DEFINED num ECHO NUM is empty, so it doesn't begin with a numeric&GOTO :EOF
FOR /l %%a IN (0,1,9) DO IF %num:~0,1%==%%a ECHO %num% Begins with numeric&GOTO :EOF
ECHO %num% Does NOT begin with a numeric
GOTO :eof
:initnum2
IF NOT DEFINED %1 ECHO %1 is empty, so it doesn't begin with a numeric&GOTO :EOF
CALL SET "$1=%%%1%%"
FOR /l %%a IN (0,1,9) DO IF %$1:~0,1%==%%a ECHO %1 (%$1%) Begins with numeric&GOTO :EOF
ECHO %1 (%$1%) Does NOT begin with a numeric
GOTO :eof
You should be able to get what you want from this demo.
#echo off
setlocal enableextensions disabledelayedexpansion
set "var=1hello"
for /f "tokens=* delims=0123456789" %%a in ("%var%") do (
if not "%%a"=="%var%" echo var starts with a number
)
If the var contents starts with a number, the token/delim management in the for command will remove it.
edited just to include the usual (included the previous code) and some less used options just in case someone is interested
#echo off
setlocal enableextensions disabledelayedexpansion
set "var=1hello"
echo(%var%
rem Option 1 - Use the for command to tokenize the string
rem A dot is added to handle empty vars
for /f "tokens=* delims=0123456789" %%a in ("%var%.") do (
if not "%%a"=="%var%." (
echo var starts with a number
) else (
echo var does not start with a number
)
)
rem Option 2 - Use set arithmetic and detect errors
rem This will fail if the string starts with + or -
set "%var%_=0"
set /a "test=%var%_" 2>nul
if not errorlevel 1 (
echo var does not start with a number
) else (
echo var starts with a number
)
rem Option 3 - Use substring operations and logic operators
set "test=%var%."
if "%test:~0,1%" GEQ "0" if "%test:~0,1%" LEQ "9" set "test="
if defined test (
echo var does not start with a number
) else (
echo var starts with a number
)
rem Option 4 - Use findstr
rem This is SLOW as findstr needs to be executed
echo(%var%|findstr /b /r /c:"[0-9]" >nul && (
echo var starts with a number
) || (
echo var does not start with a number
)
I think this is the simplest way:
#echo off
setlocal EnableDelayedExpansion
set digits=0123456789
set var=1something
if "!digits:%var:~0,1%=!" neq "%digits%" (
echo First char is digit
) else (
echo First char is not digit
)
The first character of var is tried to be removed from digits string. If such a char was a digit, digits string change; otherwise, digits string remains the same.
#echo off
setlocal
set "the_string=a23something"
for /l %%a in (%the_string% ; 1 ; %the_string%) do set "cl_string=%%~a"
if %the_string:~0,1% neq 0 if "%cl_string%" equ "0" (
echo does not start with number
) else (
echo starts with number
)
endlocal
Another approach is with FINDSTR which eventually will be slower as it is an external for cmd.exe command.
#echo off
set "the_string=something"
echo %the_string%|findstr /b /r "[0-9]" >nul 2>&1 && (
echo starts with number
) || (
echo does not start with number
)
This will work in your situation:
echo %variable%|findstr "^[a-zA-Z]" >nul && echo it starts with an alpha character
Using findstr with regexp :
#echo off
set "$string=2toto"
echo %$string:~0,1%|findstr /i "^-*0*x*[0-9][0-9]*$">nul && echo is NUM || echo Is not NUM
in place of echo is NUM or echo is not NUM you can use a goto to redirect your script the way you want it.
#echo off
set "$string=2toto"
echo %$string:~0,1%|findstr /i "^-*0*x*[0-9][0-9]*$">nul && goto:isnum || goto:isnotnum
:isnum
echo is NUM
exit/b
:isnotnum
echo is not NUM
You have to set the string as a variable; in this way you are able to extract substrings from a main string. Here is an example:
#echo off
set EXAMPLESTRING=12345abcde
set FIRSTCHARACTERSTRING=%EXAMPLESTRING:~0,1%
The result of this short script should be 1 in this case.
Then, you can set a series of conditions to verify whether the first character is a number or not:
if %FIRSTCHARACTERSTRING%==0 goto NUMBER
if %FIRSTCHARACTERSTRING%==1 goto NUMBER
if %FIRSTCHARACTERSTRING%==2 goto NUMBER
if %FIRSTCHARACTERSTRING%==3 goto NUMBER
if %FIRSTCHARACTERSTRING%==4 goto NUMBER
if %FIRSTCHARACTERSTRING%==5 goto NUMBER
if %FIRSTCHARACTERSTRING%==6 goto NUMBER
if %FIRSTCHARACTERSTRING%==7 goto NUMBER
if %FIRSTCHARACTERSTRING%==8 goto NUMBER
if %FIRSTCHARACTERSTRING%==9 goto NUMBER
goto LETTER
:NUMBER
echo The first character is a number!
goto EOF
:LETTER
echo The first character is a letter!
goto EOF
Maybe this is not the most efficient solution but it works fine and it is easier to understand.

Resources