Remove lines from hosts file with batch if already exists - batch-file

I have a batch script to add new entries based on the given IP address:
#echo off
SET NEWLINE=^& echo.
set /p ipAddress=What is the IPv4 address of the instance?
FIND /C /I "storage.app.lab" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^%ipAddress% storage.app.lab>>%WINDIR%\System32\drivers\etc\hosts
FIND /C /I "home.app.lab" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^%ipAddress% home.app.lab>>%WINDIR%\System32\drivers\etc\hosts
FIND /C /I "api.app.lab" %WINDIR%\system32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 0 ECHO %NEWLINE%^%ipAddress% api.app.lab>>%WINDIR%\System32\drivers\etc\hosts
pause
However, I want to be able to overwrite existing entries with the domain name if a new ip address is entered. For example, if an entry with the domain name of "storage.app.lab" already exists, replace it with the new IP address.
How can I achieve that without using a backup hosts file?

#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "filename1=%sourcedir%\q64587777.txt"
:: I'll just use a fixed string for the IPaddress
set "IPaddress=User-input IP address"
:: remove variables starting #
FOR /F "delims==" %%a In ('set # 2^>Nul') DO SET "%%a="
FOR /f "tokens=1*delims=:" %%a IN (
'findstr /v /N /L /C:"storage.app.lab" /C:"home.app.lab" /C:"api.app.lab" "%filename1%"'
) DO set "#%%a=%%b"
(
FOR /F "tokens=1*delims==" %%a In ('set # 2^>Nul') DO echo %%b
for %%a in ("storage.app.lab" "home.app.lab" "api.app.lab") do echo %IPaddress% %%~a
)>"%filename1%"
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances. The listing uses a setting that suits my system.
I used a file named q64587777.txt containing some dummy data for my testing.
The first few lines simply establish filename variables for testing, and a recognisable string to save re-entering data in testing.
The procedure will use variables named #* for temporary storage of the "other" lines in the file in question, so first clear out any variables that may exist that start #.
Then execute findstr and "print" lines that do NOT contain (/V) any of the /L literal strings provided as /c:"string-to-EXclude" and /N number thos lines with a leading serial number followed by a colon.
The for /f tokenises the line using the : separator as a delimiter and assigning the line number to %%a (token 1) and the remainder of the line (the data in question) to %%b. Set the environment variable #%%a to the lines found.
Then use the same principle on a set # list, which will list all variables starting # in the format #1=line one, delimiting on = and selecting the 2nd token, which is the line data originally read from the file.
And add the three new lines by construction.
Parenthesising the two for statements together gathers the echoed output which is then redirected to the original file, overwriting it.
Note that OP's code appended the (up to) three new lines. The requirement is (apparently) that the 3 lines will appear in the file, replacing any existing data for those three entries.

Related

Compare a variable with the values in an array in a batch script

I have set my arrays like this:
SET ORG[0]=Microsoft
SET ORG[1]=Google
SET ORG[2]=Yahoo
SET ORG[3]=Snapchat
SET ORG[4]=Whatsapp
SET ORG[5]=Facebook
Then I do a find in one of the files to get the value stored in the file:
For /F Tokens^=10^ Delims^=^" %%A in ('Find /I "%Client%"^<"C:\Env\Test\test.xml"') Do Echo "%%A" & SET "ORG=%%A"
Where ORG can be any of the above mentioned array values depending on what's stored in the file. For example say for this instance:
ECHO %ORG% gives Google.
I would like to compare my %ORG% value fetched from the file against the set array values and If its equal then I want my batch script to:
GOTO :Action Else
ECHO "Client Name Not Found"
I am not sure how to compare a variable with the values in the array?
for /f "tokens=1*delims==" %%a in ('set ORG[ 2^>nul ') do if "%%b"=="%ORG" goto action
echo Client not found.
The set command lists the existing variables that start ORG[ in the format org[3]=Snapchat Setting delims to = only assigns ORG[3] to %%a and Snapchat to %%b.
If such a match is found, the client is valid on the list. If the for exhausts all entries, processing simply proceeds to the next instruction in the file.
To make the comparison case-insensitive, use if /i in place of if

Batch unzip files in child folders, then copy specific files to network folder based on number in file name

I am a serious newbie at creating batch files and am hoping someone can help me. One of our staff receives zipped pdf docs by email, which she copies to a folder on her desktop. Within that folder, I would like for her to run a batch script that will
A. Unzip the zipped contents into a network directory, i.e. \server\contracts
Under this directory, the process will create folders for each group of contracts, i.e. \server\contracts\Masterson (The name of this will be same as zipped file name).
B. Then the batch process should copy a select few of the pdf documents into a network directory based on the filename. Each file contains a number, which will go in the following manner: Masterson + 1.pdf >> \server\contracts\Item1 and \server\contracts\Item2, etc. Masterson + 1.pdf will go into \server\contracts\Item1 without a folder name, as will Paisley + 1 certificate.pdf and Johnsonville + 1 document.pdf.
The problem is that the companies do not follow instructions and the number can be at the beginning, middle, or end of the file name. Also, unfortunately, there are spaces in the name of the zipped file and the pdf documents. Currently, we are only copying 4 filenames into separate directories for other people to review and validate.
Below is what I did so far looking around this site:
#Echo off
SETLOCAL
for /R "delims=\\server\contracts\RECEIVED 2017-18 APPLICATION" %%I in
("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
rem setlocal enableextensions disabledelayedexpansion
CLS
::The Input Folder
set "InputFolder=C:\Users\eartha.kitt\Desktop\Test"
::The Output Folders
set "Output1=\\server\contracts\ITEM 1 17-18 CERTS"
set "Output6=\\server\contracts\ITEM 6 SIGNATURES"
set "Output8A=\\server\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8B=\\server\contracts\ITEM 8B 16-17 REVISED CALENDARS"
set "Output8a=\\server\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8b=\\server\contracts\ITEM 8B 16-17 REVISED CALENDARS"
::The extensions to wait
set "extensions=*.pdf"
setlocal EnableDelayedExpansion
:Loop
cls
echo Waiting for file ...
for /f "usebackq delims=|" %%a in ('dir /b /s %InputFolder%\%extensions%
2^>nul') do (
rem for /r %%a in in (%InputFolder%\%extensions% 2^>nul') do (
set "Fichier=%%a"
echo Treating _^> %%a
if "!Fichier:~0,-2!"==" 1" COPY "%%~a" %Output1%
if "!Fichier:~0,-2!"==" 6" COPY "%InputFolder%\~%%a" %Output6%
if "!Fichier:~0,-3!"=="8A" COPY "%InputFolder%\%%a" %Output8A%
if "!Fichier:~0,-3!"=="8B" COPY "%InputFolder%\%%a" %Output8B%
if "!Fichier:~0,-3!"=="8a" COPY "%InputFolder%\%%a" %Output8a%
if "!Fichier:~0,-3!"=="8b" COPY "%InputFolder%\%%a" %Output8b%
::Waiting ~5 seconds
ping localhost -n 6 >nul
)
::Return to the loop
goto:Loop
Of course this doesn't work. Please help!
Well - bravo for the attempt! And so close...
Let's take the first part
for /R "delims=\\server\contracts\RECEIVED 2017-18 APPLICATION" %%I in ("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
)
What's wrong here is that the delims clause is only usable in for /f. for /r always delivers the entire filename to the metavariable %%I.
On my system I use %server%\u for testing - u is a shared resource on the server assigned to U:\ on server.
for /R "\\%server%\u\contracts\RECEIVED 2017-18 APPLICATION" %%I IN ("*.zip") do (
"%ProgramFiles(x86)%\7-Zip\7z.exe" x -y -o"%%~dpnI" "%%~fI"
worked happily for me - delivering the extracted files to "u:\contracts\RECEIVED 2017-18 APPLICATION"
The second part of your code is examining "C:\Users\eartha.kitt\Desktop\Test" not "\%server%\u\contracts\RECEIVED 2017-18 APPLICATION" - very sensibly assigned to a variablename for easy adjustment.
Here's my modified code:
SET "terminatefilename=stop.txt"
DEL "%terminatefilename%" 2>nul
rem setlocal enableextensions disabledelayedexpansion
CLS
::The Input Folder
set "InputFolder=C:\Users\eartha.kitt\Desktop\Test"
set "InputFolder=\\%server%\u\contracts\RECEIVED 2017-18 APPLICATION"
::The Output Folders
set "Output1=\\%server%\u\contracts\ITEM 1 17-18 CERTS"
set "Output6=\\%server%\u\contracts\ITEM 6 SIGNATURES"
set "Output8A=\\%server%\u\contracts\ITEM 8A 17-18 CALENDARS"
set "Output8B=\\%server%\u\contracts\ITEM 8B 16-17 REVISED CALENDARS"
FOR /f "tokens=1*delims==" %%b IN ('set output') DO MD "%%c" 2>nul
::The extensions to wait
set "extensions=*.pdf"
setlocal EnableDelayedExpansion
:Loop
cls
echo Waiting for file ...
for /f "delims=|" %%a in ('dir /b /s "%InputFolder%\%extensions%" 2^>nul') do (
rem for /r %%a in in (%InputFolder%\%extensions% 2^>nul') do (
SET "copied="
echo Treating _^> %%a
REM OPTION 1 - Key string must be at end-of name part
set "Fichier=%%~Na"
if /i "!Fichier:~0,-2!"==" 1" COPY "%%a" "%Output1%"&SET "copied=Y"
if /i "!Fichier:~0,-2!"==" 6" COPY "%%a" "%Output6%"&SET "copied=Y"
if /i "!Fichier:~0,-3!"==" 8A" COPY "%%a" "%Output8A%"&SET "copied=Y"
if /i "!Fichier:~0,-3!"==" 8B" COPY "%%a" "%Output8B%"&SET "copied=Y"
REM OPTION 2 - Key string may be anywhere in filename
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 8B" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output8B%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 8A" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output8A%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 6" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output6%"&SET "copied=Y"
)
IF NOT DEFINED copied (
echo "%%~na"|FINDSTR /i /L /C:" 1" >NUL
IF NOT ERRORLEVEL 1 COPY "%%a" "%Output1%"&SET "copied=Y"
)
)
::Waiting ~5 seconds
timeout 6 >NUL
:: Test for exit
IF EXIST "%terminatefilename%" DEL "%terminatefilename%"&GOTO :EOF
::Return to the loop
goto:Loop
First, I set up terminatefilename so that creating this file will terminate the batch (it's an infinite loop by design in your code)
Next, I overrode your inputfolder name to suit my system.
Then the output directories. I adjusted their names to suit my system. Note that batch is largely case-insensitive, so setting Output8A and Output8a is setting the same variable. The only time that batch commands are case-sensitive is the metavariable (loop-control variable) in a for statement.
Then I inserted a line to create the destination directories. This uses a set command to list the variables starting output in the format Output1=\\%server%\u\contracts\ITEM 1 17-18 CERTS (where server will have been resolved). The command reads the output of the set command, uses = as the delimiter and assigns output1 to %%b and \\%server%\u\contracts\ITEM 1 17-18 CERTS to %%c. We want to make sure the directory %%c exists, so we make it with an md command and ignore complaints that it already exists with 2>nul.
Next the for/f. for /f reads each line of (thisfilename) or ("this literal value") or ('the output of this command') but when you need to read a from a file whose name must be double-quoted beacuse it contains spaces, then the syntax is for /f "usebackq"... (idontknow) or ("this filename containing spaces") or ('ive no idea whatever') or (`the output of this command`)
So there's no need to use usebackq -- in fact, it's counterproductive.
The delims=| is optional and could be replaced by delims= as the output of a dir command will never contain | (illegal in a file or directoryname). You do need the delims clause however, as the default delimiters include Space and the default tokens is 1 so only the first string of each line output up to the first space will be assigned to %%a.
Hmm - you've remmed-out a for/r. Sadly, the target directory in the for /r can't be a metavariable.
Next, I've cleared a copied flag saying "so far, this file has not been copied"
Next, set fichier to the name-part only of the filename. Since you are using .pdf as a filter, each name output by the for/f will be a full-filename, ending in .pdf
Next, almost-correct with the battery of if statements. The /i makes the comparison case-insensitive so that it will cope with both 8a and 8A. The strings on both sides of the == must be identical to pass the == test, so you need a 3-character string in the 8 tests.
You've evidently been experimenting with the copy command and trying to feed it with appropriate strings. %%~a strips %%a of any enclosing quotes. %%a won't have enclosing quotes - just the fullfilename, so this does nothing in this instance. %InputFolder%\~%%a concatenates the values from InputFolder,"\~" and %%a - which means "%inputfolder%\~%inputfolder%\filenameandextension of %%a". The last two would be resolved to the same, bar the ~.
Since the entire filename is contained in %%a, all that's needed for the sourcefile is "%%a" - quoted as it will probably contain spaces.
Well - the destination directory (we've already established it with the for /f...%%b) can also contain spaces, so it needs to be quoted, too.
I've then set the flag copied to Y if the line took effect. Actually, it can be set to any non-empty value as the whole object is to interpret whether or not it exists with an if defined statement to bypass any later attempts to copy the same file (remember - copied is cleared for each file)
Now - the second option. This is actually a more powerful detector of the required target strings than is the substring version, and will detect the target string anywhere in the filename.
If you echo the name-part only of the file %%~na into a findstr, then set to findstr to look for the /L literal string /i case-insensitive c:"some literal string" and output ny matches found to nowhere (>nul) then findstr will set errorlevel to 0 if found and 1 otherwise. (the /L is superfluous here, I use it habitually to remind me I'm working with literal strings, not regular expressions)
If errorlevel n will be true if errorlevel is currently n or greater than n, so if the string is found, we do the copy and set the copied flag as before.
I reversed the order of tests because it was easier for me to do using the editor I use.
Now - there's a downside to this approach. It's a double-edged sword. Since the target string is detected wherever it appears in the filename, whatever whatever 10 something something.pdf will pass the test for 1 because Space1 appears in its name.
When the loop has finished, use timeout to wait, redirecting the output to nul to make it pipe down. Note that your delay was inside the for loop - so it would have waited 6 seconds after processing each file, not 6 seconds after processing an entire batch.
Finally, if you create terminatefilename from anothe cmd instance, the batch will exit cleanly and kill terminatefilename for you. Much cleaner than control-c.
A last note: Since you are copying the file, not MOVEing it, it will still exist in the same place presumably after the 6 seconds has elapsed and will be endlessly copied and recopied. You'd probably need to make adjustments to achieve the desired result.

print specific lines from a batch file

I am trying to print Line 4, Col 21-50 out of a text file, can this be simply done under Windows somehow? I've been trying to do this:
FOR /F "usebackq tokens=1 delims=-" %G IN (%COMPUTERNAME%.txt) DO ECHO %G
This is just working out terribly. Can't I just print a specific set of lines?
I need this script to be run on multiple computers, ideally I'd like to convert it to a variable for use with slmgr -ipk, maybe someone has a better suggestion?
Contents of text file (I want the XXXXX-XXXXX-XXXXX-XXXXX-XXXXX portion):
==================================================
Product Name : Windows 7 Professional
Product ID : 00371-OEM-9044632-95844
Product Key : XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
Installation Folder : C:\Windows
Service Pack : Service Pack 1
Computer Name : LIBRA
Modified Time : 6/4/2015 7:26:54 PM
==================================================
if you want only the "Product Key" line you can try with
type %COMPUTERNAME%.txt|find /i "Product Key"
or
for /f "tokens=2 delims=:" %%# in (' type %COMPUTERNAME%.txt^|find /i "Product Key"') do echo %%#
For the task at hand, npocmaka's answer is the best suitable approach, as it does not insist on a fixed position of the string to extract from the file.
However, I want to provide a variant that sticks to a certain position.
The following code extracts the string placed at columns 21 to 50 in line 4 of file list.txt (the result is echoed (enclosed in "") and stored in variable LINE_TXT (without ""):
#echo off
for /F "tokens=1,* delims=:" %%L in (
'findstr /N /R ".*" "list.txt"'
) do (
if %%L equ 4 (
set "LINE_TXT=%%M"
goto :NEXT
)
)
:NEXT
if defined LINE_TXT set "LINE_TXT=%LINE_TXT:~20,29%"
echo."%LINE_TXT%"
The goto :NEXT command terminates the for /F loop at the given line; this is not mandatory but will improve performance for huge files (as long as the given line number is quite small).
To be more flexible, the following code can be used (define the string position in the initial set block):
#echo off
rem Define the string position here:
set FILE_TXT="list.txt"
set LINE_NUM=4
set COL_FROM=21
set COL_UPTO=50
setlocal EnableDelayedExpansion
set /A COL_UPTO-=COL_FROM
set /A COL_FROM-=1
for /F "tokens=1,* delims=:" %%L in (
'findstr /N /R ".*" %FILE_TXT%'
) do (
if %%L equ %LINE_NUM% (
set "LINE_TXT=%%M"
if defined LINE_TXT (
set "LINE_TXT=!LINE_TXT:~%COL_FROM%,%COL_UPTO%!"
)
goto :NEXT
)
)
:NEXT
endlocal & set "LINE_TXT=%LINE_TXT%"
echo."%LINE_TXT%"
Both of the above code snippets rely on the output of findstr /N /R ".*", which returns every line that matches the regular expression .*, meaning zero or more characters, which in turn is actually true for every line in the file; however, the switch /N defines to prefix each line with its line number, which I extract and compare with the originally defined one.
Here is another variant which uses for /F to directly loop through the content (lines) of the given text file, without using findstr:
#echo off
for /F "usebackq skip=3 eol== delims=" %%L in (
"list.txt"
) do (
set "LINE_TXT=%%L"
goto :NEXT
)
:NEXT
if defined LINE_TXT set "LINE_TXT=%LINE_TXT:~20,29%"
echo."%LINE_TXT%"
This method has got the better performance, because there is the skip option which skips parsing of and iterating through all lines (1 to 3) before the line of interest (4), opposed to the findstring variant.
However, there is one disadvantage:
for /F features an eol option which defines a character interpreted as line comment (and defaults to ;); there is no way to switch this option off as long as delims= defines no delimiters (last position in option string), which is mandatory here to return the line as is; so you have to find a character that does not appear as the first one in any line (I defined = here because your sample text file uses this as header/footer character only).
To extract a string from line 1, remove the skip option as skip=0 results in a syntax error.
Note that goto :NEXT is required here; otherwise, the last (non-empty) line of the file is extracted.
Although for /F does not iterate any empty lines in the file, this is no problem here as the skip option does not check the line content and skip over empty lines as well.
Finally, here is one more approach using more +3 where no text parsing is done. However, a temporary file is needed here to pass the text of the desired line to the variable LINE_TXT:
#echo off
set LINE_TXT=
more +3 "list.txt" > "list.tmp"
set /P LINE_TXT= < "list.tmp"
del /Q "list.tmp"
if defined LINE_TXT set "LINE_TXT=%LINE_TXT:~20,29%"
echo."%LINE_TXT%"
exit /B 0
This method avoids for /F and therefore the problem with the unwanted eol option as mentioned in the above solution. But this does not handle tabs correctly as more substitutes them with spaces (8 indent spaces as per default and configurable by the /Tn switch where n is the number of spaces).

Batch Script: Search thru multiple files for part of an IP address and log it

I have multiple TraceRT log files containing 30 hops. I'm only looking for similar IP (ex. 192.168.1) and would like to log it on one file with:
1) Successful: %IP% found in %Filename%
2) Fail: Specified IP not found in %Filename%
I'm trying to use:
rem************************************************************
:START
# ECHO OFF
rem US date
set YEAR=%DATE:~10,4%
set MONTH=%DATE:~4,2%
set DAY=%DATE:~7,2%
rem US hour
set HOUR=%TIME:~0,2%
set MIN=%TIME:~3,2%
set SEC=%TIME:~6,2%
set HUNDREDS=%TIME:~9,2%
set HOURMIN=%HOUR%%MIN%
rem Make sure that hour has two digits
IF %HOUR% GEQ 10 goto twoh
set HOUR1=%TIME:~1,1%
set TWOHOUR=0%HOUR1%
goto fulltid
:twoh
set TWOHOUR=%HOUR%
:fulltid
set FULLTIME=%TWOHOUR%'%MIN%'%SEC%'%HUNDREDS%
set FTIME=%TWOHOUR%:%MIN%:%SEC%
#echo off & setLocal EnableDELAYedeXpansion
findstr /m "192.168.1" *.txt > FILENAME
echo on
for /f "tokens=*" %%a in (*.txt ^| find "192.168.1") do (
IF %%a neq %%b (
echo Suscessful: %%a %FILENAME% >> Log%YEAR%%MONTH%%DAY%.txt
) ELSE (
echo Fail: Specified IP not found in %FILENAME% >> Log%YEAR%%MONTH%%DAY%.txt
)
)
goto START
rem************************************************************
You have specified an invalid pipe | find. You cannot pipe (a) text file(s) into a command.
Either provide the file(s) as argument(s) to find, or use redirection (this works for a single file only but not for multiple ones nor */? patterns though).
You are using for /f not correctly.
It looks as if you wanted to parse the output of find. To accomplish that, but you must enclose the command within single-quotes '. Type for /? and see the help text for more details.
The following line of code should work:
for /f "tokens=*" %%a in ('find "192.168.1" *.txt') do (
To get current date and time, I strongly recommend to read variables %DATE% and %TIME% once only and within a single line! Otherwise you might run into problems, especially concerning the fractional seconds, which might not be equal between consecutive expansions.
To ensure %HOUR% to have two digits, you simply need to use set HOUR=0%HOUR% then set HOUR=%HOUR:~-2%.
Since a one-digit %HOUR% is prefixed by a space here, you can have it even simpler (thanks for your comment, #Stephan!) by just replacing the space by a zero: set HOUR=%HOUR: =0%.

How do I exclude specific file names from an MS DOS dir list?

I am creating an MS DOS batch script that needs to list every .bat file in the current directory, but not show autoexec.bat or other utilities or systems .bat files that shouldn't be run by the user.
I currently have DIR "*.bat" /B /P
This lists all .bat files appropriately, but it shows autoexec.bat. How would I exclude that from the list? Also slightly important, how could I chop off the file extensions and show more than the 7-characters DOS limits files to?
Constraints: I am not able to use a DOS version above WinME. That is the version I am using.
Thanks for any help.
EDIT:
There is plenty of information on the internet about doing this, but it is all in the windows command processor, not MS DOS. Please understand that DOS and the Command Prompt are not the same thing.
#echo off
setlocal EnableDelayedExpansion
rem Add more names separated with slashes here:
set exclude=/autoexec/
for %%a in (*.bat) do (
if "!exclude:/%%~Na/=!" equ "%exclude%" (
echo %%~Na
)
)
EDIT: Some explanations added
Batch file processing is slow, so you should use techniques that allows a Batch file to run faster. For example:
Try to use the minimum lines/commands to achieve a certain result. Try to avoid external commands (*.exe files) like find, findstr, fc, etc. specially if they work on small amounts of data; use if command instead.
Use for %%a in (*.bat)... instead of for /F %%a in ('dir /B *.bat').... The second method requires to execute cmd.exe and store its output in a file before for command can process its lines.
Avoid pipes and use redirections instead. A pipe require the execution of two copies of cmd.exe to process the command at each side of the pipe.
A simple way to check if a variable contain a given string is trying to delete the string from the variable: if the result is different then the string exists in the variable: if "!variable:%string%=!" neq "%variable%" echo The string is in the variable.
Previous method may also be used to check if a variable have anyone of a list of values: set list=one two three, if "!list:%variable%=!" neq "%list%" echo The variable have one value from the list. If the values of the list may have spaces, they must be separated by another delimiter.
EDIT: New version added as answer to new comments
The easiest way to pause one page at a time is to use more filter this way:
theBatchFile | more
However, the program must reorder the output in order to show it in columns. The new version below achieve both things, so it does not require more filter; you just need to set the desired number of columns and rows per page.
#echo off
setlocal EnableDelayedExpansion
rem Add more names separated with slashes here:
set exclude=/autoexec/
rem Set the first two next variables as desired:
set /A columns=5, rows=41, wide=(80-columns)/columns, col=0, row=0
rem Create filling spaces to align columns
set spaces=
for /L %%a in (1,1,%wide%) do set spaces= !spaces!
set line=
for %%a in (*.bat) do (
if "!exclude:/%%~Na/=!" equ "%exclude%" (
rem If this column is less than the limit...
set /A col+=1
if !col! lss %columns% (
rem ... add it to current line
set name=%%~Na%spaces%
set "line=!line!!name:~0,%wide%! "
) else (
rem ... show current line and reset it
set name=%%~Na
echo !line!!name:~0,%wide%!
set line=
set /a col=0, row+=1
rem If this row is equal to the limit...
if !row! equ %rows% (
rem ...do a pause and reset row
pause
set row=0
)
)
)
)
rem Show last line, if any
if defined line echo %line%
Antonio
attrib +h autoexec.bat
should hide autoexec.bat and it should thus not appear in the list
DIR "*.bat" /B /P | find /v "autoexec" | for %i in (*.bat) do #echo %~ni
Using for to process each file name individually:
setlocal enabledelayedexpansion
for /f %%i in ('dir "*.bat" /b') do (
set system=0
if "%%i"=="autoexec.bat" set system=1
if "%%i"=="somesystem.bat" set system=1
if !system!==0 echo %%i
)
Another method without variables:
for /f %%i in ('dir "*.bat" /b') do call :test %%i
goto continue
:test
if "%1"=="autoexec.bat" goto :eof
if "%1"=="somesystem.bat" goto :eof
echo %1
goto :eof
:continue
For both, you can add new filenames to exclude from the list.

Resources