INFO for DOS
Instead of reading this online, you can download
my 4DOS BATFAQ
I have ceased to mirror the frequent updates of Prof. Salmi's BATFAQ. I think I've achieved my original goal to show that a 4DOS solution is shorter, faster, easier to implement, easier to understand and easier to maintain. If you need another 4DOS answer to one of Prof. Salmi's later batch FAQs, please contact the newsgroup comp.os.msdos.4dos or ask me by email.
In TSBATnn.ZIP, Prof. Timo Salmi, batch expert and regular of the alt.msdos.batch Usenet group, has written and maintains a very hefty and thorough FAQ dealing with vanilla DOS batch problems named 1BATFAQ.TXT.
His syntax here isn't very exact, however, because batches are executed not by the DOS (=Disk Operating System) per se, but specifically by the command processor, usually named COMMAND.COM and included with the operating system. Like many utilities provided by MS and its rivals, its abilities aren't necessarily state of the art, and can (and should) be replaced by the power user.
In question (69) Prof. Salmi deals with 4DOS, which is my special interest (surprise, surprise!).
4DOS.COM is an alternative command processor by JP Software, with enhanced features all around, running under practically any DOS version. It is so powerful, in fact, that it is mostly unnecessary to resort to any external executable or language, like Prof. Salmi often has to do in his solutions, as I will show you.
In most cases of this FAQ, a one-line solution is possible under 4DOS.COM, replacing a lengthy, convoluted and non-intuitive COMMAND.COM solution. My thanks go to all people who sent me corrections or amendments.
I have mirrored the questions according to Prof. Salmi's FAQ, and given (the) short 4DOS solutions, to give the reader the chance to view both side by side for comparison..
I'll start, however, out of order with Prof. Salmi's remarks about 4DOS (question 69) and my answers to them.
(Note: bold text is quoted from Prof. Salmi's 1BATFAQ.TXT)
69) All these solutions are for wimps. Why not rather use 4DOS?
I know that for most batch fans the real challenge is to do the nearly impossible with the somewhat performance challenged means MS (and others) bestow on you in the form of COMMAND.COM. I can understand and respect that. There are many situations, however, where a batch solution is not sought as "art pour l'art", but to solve real problems in a robust and maintainable way.
So I cannot let go these statements and dire warnings by Prof. Salmi uncommented:
The extra features are galore, and the "hassle" to change the command interpreter burns down to unzipping a file in a new directory and changing the "SHELL=..." line in CONFIG.SYS to point to 4DOS.COM. The latest 4DOS version will do all this automatically for you.
There _are_ some incompatibilities, mainly when undocumented "features" of COMMAND.COM (which version, btw, ?) are exploited. So there _may_ be a number of your batches that will not work without minor changes. 4DOS.COM uses a superset of COMMAND.COM commands, and most batches will run unchanged under it. You don't even have to ditch your old command.com: you can start it from your 4DOS shell to run your old batch files.
I'll still have to see a program that ceases working properly under 4DOS.COM (and why should a properly written program care?). It's when you shell out from a (really rare) not-so-well-written program that has a hard-coded shell-out to COMMAND.COM instead of %comspec% that problems occur. Again: these are rare and often easily solved.
On the plus side, you can really start to produce. You can structure your batches with IFF ... THEN ... ELSE, DO loops, SWITCH ... CASEs, GOSUB labels and so on, as I'll show you if you hang on.
You can stop worrying about how to get user input, a (any) string into a variable, or a date into a filename. You have more than a hundred internal variables and functions at your command(line), that will give you access to and info about most parts of your system. And yes, you can do more than basic arithmetic with @EVAL. In short, the information you now wrestle to get is already there and waiting for you to do something sensible with it.
You have additional internal commands like TOUCH, LIST, SELECT, GLOBAL, EXCEPT and dozens of others. Have you noticed how often you have to resort to an external 3rd-party utility or even a complete language like BASIC or PASCAL using COMMAND.COM? After starting to use 4DOS, you will quickly and gladly delete a megabyte of various tools (all with different syntax!) from your disk. You can have aliases (like memory resident batches or DOSKEY macros), fuzzy directory change, a fully editable command line with history, 16 available colors even without ANSI.SYS, and more.
Last not least you have a command-line sensitive HELP function at your fingertip: just hit the F1 key.
you could start to use 4DOS and finally get a life :-)
This is now obsolete, because 4DOS 7.50 has been declared freeware. You can take it with you and copy it freely to every system you work on. Is your favourite editor available on every system? Same solution: take a disk/CD with the needed files with you and work from that or reserve yourself some diskspace on the system.
Now let's start on the FAQs and make "short" work of them: a quick compare of the relative file sizes will give you a very accurate first impression.
Use the INI-directive "BatchEcho = NO" in your 4DOS.INI file to make it standard. BTW, @ECHO OFF is version-independant in 4DOS :-)
2) Deleting all files without being prompted "Are you sure (Y/N)?"
Make an alias for the DEL command, e.g.
DEL=*DEL /Y %&
3) Is it possible to nest for loops in batch files?
4DOS knows not only the FOR command, but also the more flexible DO ... ENDDO loop. You can nest DO loops up to 15 levels deep, nesting of FOR loops depends on available memory.
4) How can I check in a batch whether a directory exists?
IF ISDIR path ...
If the subdirectory exists, the condition is true. For compatibility with Novell DOS/OpenDOS, DIREXIST may be used as a synonym for ISDIR.
5) Checking that a program is available at the current directory or at path
Besides "IF EXIST path/file ..." you can check for executables in the path ("WHICH command.exe", new in 4DOS 7.00) which will tell you if that command is an binary executable file, a batch or an alias. You can use the %@SEARCH[filename] function, which will tell you the whole path/filename if the file exists in the path.
6) Is it possible to use subroutines and recursion in batches?
Easily in 4DOS: use the "GOSUB label" command to branch to a subroutine and "RETURN" to do just that. Use "DO n", "DO x=0 to 10", "DO UNTIL ..." or "DO FOREVER" to loop until a certain condition is met.
7) How can I convert a lowercase parameter to uppercase?
Use the %@UPPER function. Of course there's %@LOWER too.
8) Is there an easy way to append a new directory to the path?
4DOS supports a path length of > 500 characters. To append to it from the command line, use "ESET %path". Or use
9) How can I compare if two files are identical?
Besides resorting to an external FC utility, you can check all attributes of the file(s) using functions like %@FILESIZE, %@FILEDATE, %@FILETIME, you can compare each line of both files using @line on a string basis or on ascii value basis of each char with %@ASCII. It's easy to write your own filecompare tool using only inbuilt functions.
10) Writing an empty line to the screen. How is that done?
Use "ECHO." or "ECHO `` " If your aims are higher, you can use SCRPUT, VSCRPUT, DRAWBOX, DRAWHLINE and DRAWVLINE to put characters, boxes and lines anywhere on your screen, in 16 available colors and several styles.
11) A tip: Customizing the pause message
4DOS knows "PAUSE [text]" to display a custom message. It also knows DELAY, which can time a pause from milliseconds to 1 hour.
12) A tip: Complicated renaming of files with for
Replacing FOR with DO ... ENDDO, you can rename files found based on wildcards, ranges, or include lists. Depending on what result you want to achieve, there are internal variables und functions for all aspects of the date and time, %@INC and %@DEC to increase and (yeah!) decrease numbers, %@EVAL for arithmetic, and everything you need for string handling of filenames. REN's /N switch will show the results without doing any actual renaming.
13) How can I check if the file name given included wildcards?
Use the %@INDEX[string1,string2] function, e.g.:
IF %@INDEX[file,?] ne -1 .or. %@INDEX[file,*] ne -1 ECHO Wildcard found!
14) Is it possible to prevent the user from breaking the batch?
Yes. Use BREAK OFF and BREAK ON to allow it once more..
15) Can I prevent a break from bypassing the autoexec.bat?
See above. But that's not very reliable, at least not under Windows95 /MS-DOS 7 and up. Hitting F8 allows you to step through the startup files, as long as you have not "BootKeys=0" in there. Prof. Salmi's method using CTTY suffers the same limitation.
16) How can I extract the extension of a file name?
Use function %@EXT[filename]
17) Information on the quote character %
is not a "quote character". It is the metacharacter used for variable
substitution. The quote characters are, of course, "`" and """.
To echo the string "%1", you can use ECHO %%1, but the 4DOS way is to escape the char that has a special meaning. To do that, you prepend the problematic character with the escape character, (ALT 024), or its representative "%=", so to echo the string "%1" you use >
18) Eliminating auxiliary batches (making do with the main batch)
A recursion problem easily solved by using GOSUB and RETURN.
19) Utilizing the subst command in paths
The use of SUBST isn't recommended under Windows. 4DOS knows PUSHD and POPD, uses fuzzy CD and CDD (to change drives, too), aliases and variables. On my system I write "4D" on the command line and get a selection menu for all dirs starting with "4D".
20) How can I run a batch once a week (testing for the weekday)
4DOS has an example batch called ONCEADAY.BTM. Using functions like %@DOW (day of the week), %@DOWI (DOW as integer), %@DOY (yes, day of the year) it's easy to write a batch that will only execute once a day, week, month or year (or any other regular interval you care to name).
21) How can I test if a given file name includes the path?
Use %@PATH[filename] (or %@PATH[%filename], if you already have a variable called filename) to extract the path from any given filename.
22) How can I display the time without having to press enter?
Use the internal variables %_TIME, or %_HOUR, %_MINUTE, %_SECOND, use TIMER to time events, or %@TIME to convert any time to number of seconds since midnight.
shows the current time.
23) Alternatives for testing for the errorlevel value
Most internal 4DOS commands set errorlevel values. 4DOS has internal variables for external program exit code (%?), reason for external program termination (%??), exit code last internal command (%_?) and last DOS error (%_SYSERR). Since 4DOS is able to determine values equal, less than, less or equal, greater, greater or equal, unequal to another value, it's easy to catch specific errors:
IF "%_?" NE "" GOSUB ERR_HANDLER
IF %_? == 1 ...
IF %_? == 2 ...
The "ON ERROR..." command is also available to catch (and recover from) errors.
24) About redirecting a batch file's output
Redirection and piping is enhanced in 4DOS. You can redirect standard output, standard error or both, creating or appending to a file, a device or the Windows clipboard. Piping is enhanced by the TEE and Y "pipe fittings". And obviously you can
BATCHNAME > OUTFILE
25) How can I test if m batch has sufficient environment space?
For a minmum of 200 bytes
IF %_ENV .LT. 200 ECHO Not enough environment space
Then there's the "EnvFree=200" .INI-directive which would ensure that any new shell starts with at least 200 bytes free env space.
26) Is there a simple trick to "disable" or hide a drive?
Only using external utils.
27) How can I send an escape sequence to the printer?
See 17) for info about the escape character. To send e.g. a form feed followed by the sequence ESC Y to the printer, you can use this command:
ECHOS %=f%=eY > PRN
28) Is it possible to create a random string in a batch?
Use %@RANDOM to create random numbers, %@UNIQUE to create unique files with random names. Using one or both functions you can create random numbers or strings of any length.
29) Is it possible in a batch to find out the length of a string?
30) How to obtain the MS-DOS version into an environment variable?
%_DOSVER to get the version, %_DOS to get the operating system, %_4DOS to
get the 4DOS version, %_WIN to get the Windows version...
31) How can I find out the number of regular files on a drive?
To get the number of files in directory, e.g. the root of A:, use
Prof. Salmi's example to get the filenumber of a whole drive using ATTRIB is ingenious, and can be enhanced in 4DOS:
ATTRIB /S C:\* | FIND /c "\" | INPUT %%filenum
Since internal FFIND cannot display (up to now) nonmatching lines of a file, you could use 4DOS' TYPE instead. The /L switch prepends each line with the line number:
TYPE /L infile outfile
which will prepend each line of infile with a linenumber in outfile.
33) Storing and returning to the original directory (push and pop)
4DOS knows PUSHD and POPD commands.
34) Enticing the current date into an environment variable
"Enticing" in 4DOS means using the internal variable %_DATE.
35) A tip for power users. Identifying the individual PC.
Setting a var for the PC in AUTOEXEC.BAT is trivial. You could probably use the drive's unique (?) number or label. The drive label can be accessed with %@LABEL[drive], the serial number (e.g. for drive A:) with
SET sernum=%@WORD[-0,%@EXECSTR[vol a:]]
36) For loop and redirection quirks
The (not working under COMMAND.COM!) problematic line in Prof. Salmi's FAQ
FOR %%f IN (a b c d) DO IF EXIST %%f ECHO put %%f >> tmpfile
works as expected under 4DOS.COM.
37) Is it possible to traverse a directory tree with a batch?
Most file operation commands have the /S (for subdirectories) switch. Then there's the GLOBAL command, the TREE command...
38) Is it possible to echo the redirection symbol in a batch?
Use the representation of the escape character: Ctrl-X, %=, Alt-024 or use backquotes:
all work. Then there is TEXT ... ENDTEXT which will put any text between these lines on the screen even if it contains reserved characters..
39) How can I extract the file basename?
40) A batch to put user input into an environment variable
Use INPUT to put strings, INKEY to put single keystrokes into variables.
41) How can I get the last replaceable parameter given to a batch?
%0 contains the name of the batch file as it was entered on the command line, %# contains the number of command line arguments, and %n& contains the complete command-line tail starting with argument number n. So
contains the last parameter.
Note that 4DOS normally uses only a leading "%" to indicate a variable. But for compatibility with command.com it understands the trailing "%" too.
In the example above square brackets are used to indicate the end of "%#". Syntax like "%#%%&" or "%#%%&%" is allowed as well.
42) Creating an empty file if the file does not already exist
43) How can I change or remove the disk volume serial number?
You need to use an external like DEBUG.EXE. A 4DOS batch to do that with a comfortable user interface is XSERIAL.BTM in my 4XBTM collection.
44) How to pause in a batch for a preset number of seconds?
DELAY n (number of seconds)
45) Where can I find a program to compile batches into COMs or EXEs?
Batch compilers work only badly for COMMAND.COM compatible batches (each version introduces new behaviour of old commands, and most batch compilers haven't been updated for some time). 4DOS batches use a superset of DOS batch commands, so batch compilers will not know what to do with them. 4DOS has BATCOMP.EXE, which will compress and (weakly) encrypt a batch, making it difficult for the novice user to decrypt and change that batch.
46) How can I test whether a disk is empty or not?
Several possibilities: %@FILES[A:\] will tell you if there are files in the root dir, %@FILESIZE[A:\*.*] will tell you their size (0?), %@DISKUSED[a:] will tell you how many bytes on A: are used by files.
47) How can I run a different batch depending on the weekday?
IF %_DOWI == 0 call sunday.bat
48) Can one put line numbers into a file with just batch commands?
Already answered (32)
The COPY command (and many others) understands date ranges, e.g.
COPY /[d-0] *.* d:\backup\
50) How can I traverse all files of a directory in a batch?
Use DO as in
DO x IN *.*
FOR %x in (*.*) DO (
51) How can I step through a batch a command at a time to debug it?
4DOS has a built-in batch debugger which allows you to step through a batch, inspect the variable values, expand the current command, skip a line ...
52) How to display all files made or updated on a day or today?
The DIR command understands ranges (date, time and size) too. So the command
DIR /[d-1,+0] *.*
will display all files in the current dir created yesterday.
53) How can I make a list of all my files and locate a certain file?
To make a list of all your files on all drives (C:, D:, E:):
FOR %x IN (c: d: e:) DO DIR /B/F/S * > filelist.dat
Locate a filename:
FFIND /B/T"filename" filelist.dat
54) How can I tell if a batch is running in a Windows dosbox?
Use the internal %_WIN variable, which will tell you which Windows variant you're under, too.
55) How can I test if there is a disk in a floppy disk drive?
56) Could you please solve this problem for me with a batch?
We are always happy to help a civil questioner at comp.os.msdos.4dos.
57) How can I make a loop that is repeated a preset number of times?
Use "DO 4" or "DO n=1 to 4"
58) How can I display the contents of the memory?
Use external "MEM /C | MORE" for an overview, which has nothing to do with 4DOS. You could use the internal functions %@DOSMEM, %@XMS, %@EMS, %@EXTENDED to check free memory. To display the actual content you'll have to use DEBUG.EXE.
59) How get today's date into a six-character environment variable?
60) How can I find and copy the files updated today in a directory?
Already answered (49)
COPY /[d-0] dir\*.* newdir\
61) How can I test in a batch whether a TSR program has been loaded?
Looking for the memory footprint of a TSR can be done with internal (FIND.EXE is an external program) means only, which means faster:
MEM /C | FFIND /K/M/Tsmartdrv | INPUT %%test
62) Putting the current drive letter into an environment variable.
No need: the current drive is in internal var %_DISK
63) How can I extract the drive letter from a full file path?
Use the string handling capabilities of 4DOS: assuming the full path is in var %fp, easiest would be
64) How can I write a "SLEEP" command to pause for a certain time?
Already answered in (44). Use DELAY.
65) How can I put comments into a batch file?
"REM" and "::" can both be used.
66) How can I echo just the word "off" in a batch file?
works just the same as under COMMAND.COM. If the goal is to just place the word "OFF" on the screenin a certain position, you can alternatively use
SCREEN row col OFF
You would use %@LEFT or, just to demonstrate another string handling command,
where "filename" can be a variable.
68) How can I compare two numbers with batch commands?
With pure numbers 4DOS does a numerical compare, e.g.
IF 19 GT 2 ECHO true
To do a string compare, use
IF "2" GT "19" ECHO true also
You can use .AND., .OR. and .XOR. to refine your comparison:
IF 19 GT 2 .AND. "2" GT "19" ECHO both true
69) ---------- Moved to Introduction-----------------------
70) How can I give more than the nine parameters to a batch?
4DOS routinely handles up to 127 parameters. So no more need to SHIFT vars (but you _can_, of course).
71) How can I update copy files from one directory to another?
4DOS' COPY command has the /U switch. Using this, COPY will only copy each source file if it is newer than a matching destination file or if a matching destination file does not exist:
COPY /U firstdir\*.* seconddir\
72) How can I best clear all the files from my TEMP directory?
Instead of using external DELTREE.EXE, use the internal DEL command (with due caution!):
DEL /S /X /Y /Z dirname
will leave your dirname dir pristinely clear. You can test the action of this (and many other) commands with the /N switch. This will do anything but actually delete the files, giving you a chance beforehand to see what would get deleted.
73) How can I check the number of parameters given to a batch?
It's in the internal "%#" variable.
74) How can I locate and e.g. delete all *.TMP files on a drive?
For drive C: use
DEL /S C:\*.tmp
which will delete matching files in all subdirectories too. Again: you may want to test with the /N switch mentioned in (72)
75) How can I rename all files sequentially in a directory?
You'd write a short batch (you can always convert it to an alias later). Let's assume the files are in your working dir, and that you want 4 digits in that filename with leading zeros, starting with 0000:
would rename all files to 0000.TXT, 0001.TXT etc. With an additional line you could have those files sorted for date, time, name, extension, size etc. before renaming, and you can test your batch using REN's /N switch, which will show you the results without doing any actual renaming.
76) How to search all the *.txt files on a drive for a word?
4DOS' FFIND with switch /S will do that for you:
FFIND /S /Tmyword C:\*.txt
77) How can I give multiple commands on one line?
4DOS knows a command separator: "^" or the internal variable representing it: "%+" This lets you write several independant commands on one line:
BEEP ^ ECHO Did I get your attention? ^ BEEP
78) Is there a batch to individually zip each file in a directory?
FOR %x IN (*.*) DO (
IF "%@ext[%x]" ne "ZIP" PKZIP -m %@name[%x] %x
79) A batch to substitute a string through a set of text files?
You _can_ write a 4DOS batch file for this, but it would not be a job for the novice and at least 10 lines long :-). I agree with Prof. Salmi that it's best handled by SED, AWK or some similar external tool.
80) Where do I find a good book or WWW page on batch programming?
81) How to read a file's date and time into environment variables?
Use the %@FILEDATE and %@FILETIME functions:
You can do arithmetic with dates and times, too.
82) How would I get a beep in a batch file?
Use "BEEP" or "BEEP frequency duration" if you want something fancy.
83) Y2K: My old BIOS gives a wrong year at boot. How can I fix it?
Assuming the day and month are correct and the year needs to be changed, you'd place a line like
in your AUTOEXEC.BAT, or you can get really fancy and evaluate the current year by adding a fixed amount to the wrong year, eg
DATE %_month/%_day/%@eval[19%_year + 20]
This assumes the mm/dd/yy format.
84) Is there a batch to drop the first letter of a file name?
Assuming the filename is in a variable (%1 in a batch file?) you'd use
REN %1 %@instr[1,,%1]
Be careful. There may be filenames with only one character!
85) How do I close the command window once my batch file has run?
Same as under COMMAND.COM. Check the "Close when finished" box in the programm properties of your DOS box, use EXIT or CLS as the last line of your batch.
Nice Freudian slip here ;-)
I don't agree with Prof. Salmi here.
DOS has a very large user base, and existing batches will be used for quite some time to come.
But With the advent of W2K aka NT5 new work will tend to be done under NT's CMD.EXE, which is reasonably compatible with COMMAND.COM. Migrating heritage DOS batches to NT isn't too difficult.
So my prediction is: active DOS batching will decline faster than usually expected (my bet is ~2 years), NT batching will correspondingly prosper. It might be prudent to have a look at 4NT, the 4DOS answer to CMD.EXE, and mostly compatible with 4DOS, too.
87) How can I test for the existence of a substring in a string?
IF %@INDEX[string,substring] NE -1 ECHO It's there!
88) How can I put MS-DOS FIND results into an environment variable?
You'd prefer to use the faster internal FFIND command, but for both it's easy to pipe the results into a variable (%newvar):
FIND "your specs here" | INPUT %%newvar
FFIND "your specs here" | INPUT %%newvar
89) How to get months as letters and years in four digits in DIR?
Using 4DOS, you can write your own DIR command with customized display. Assuming you want to see the 8.3 filename, filesize, filedate as above for the parameter (%1) of your customized command, you could write (%= is the line continuation var):
FOR /A:-d %fn IN ("%1") DO (
This is slow, but much faster than working with external utils in a saved-to-disk file and displaying the results.
90) Isn't MS-DOS dead with W2K? So why bother with MS-DOS batches?
91) How can I exit the called batch without returning to the first?
Prof. Salmi's solution is valid under 4DOS, too, but 4DOS also has the "CANCEL" command, which terminates all batch processing regardless of nesting level.
92) How do I create a sequence of directories from 1 to MaxValue?
No need to employ another language: 4DOS can do it like this, assuming you want 5 digits and leading zeros like DIR00000 to DIR99999:
:: give start and max value as parameter 1 and 2 on the command line
DO n=%1 TO %2
93) How do I add +1 to a variable in a batch?
4DOS has the @EVAL function, so you could
SET newvar=%@EVAL[%oldvar + 1]
or, since version 5.5 as far as I remember, %@INC:
94) How to copy the errorlevel into a variable in a batch?
No need, it already is in an internal 4DOS var. See (23).
95) How can I test for a zero byte file or a larger file?
The %@FILESIZE[file] function shows you the size of a file, in Bytes, Kilo- or Megabytes if you wish:
IF %@FILESIZE[file] == 0 ...
or, for other filesizes, eg. lighter or equal to 100 bytes:
IF %@FILESIZE[file] le 100 ...
or greater or equal to 1 MB:
IF %@FILESIZE[file] gt 1000000 ...
96) How to show the last N lines of a file using DOS batch files?
4DOS can determine the number of lines in a file with %@LINES[file], the content of a particular line n with %@LINE[n,file]. So to show the last 10 lines of a file given in parameter 1 you would write something simple like
DO n=%@EVAL[%ln - 10] TO %ln
97) How do I get the path of a file located somewhere on my disk?
DIR /B/J/S myfile
would give you only the full path and filename of files matching the myfile spec. You could redirect the output to a file and use this as input for another command (Most 4DOS commands can use filelists generated like this). Let's assume you want to delete all these files on all drives:
DIR /B/J/S C:\myfile > tempfile.dat
DIR /B/J/S D:\myfile >> tempfile.dat
DIR /B/J/S E:\myfile >> tempfile.dat
or, using multiple wildcards:
DIR /B/J/S C:\myfile D:\myfile E:\myfile > tempfile.dat
98) How to read a file's attributes into environment variables?
For a file with the attributes R,H and A the function %@ATTRIB[file] would return "RH_A_" (without the quotes):
99) Is it possible to echo without linefeed like the Unix echo -n?
Yes. ECHOS does that:
100) How can I detect the F1-F10 function keys in a batch?
The INKEY command is used to get single key input into a variable. This includes the function keys. To get the F1 key, you'd use
IF %key eq @59 ...
101) How can I get the free size and total size of a drive?
For drive C: you'd use the internal command
or the (you guessed it!) internal functions:
ECHO %@DISKFREE[C:] of %@DISKTOTAL[C:] bytes free on drive C:
102) How can I search for a string through a directory of files?
FFIND /S /T"string" dir\*.*
103) How do I find the largest numeric extension and add +1 to it?
We'll assume that there are files with other extensions mixed with those numerical extension files that interest us, to make it a little bit more difficult, and to give me cause to introduce you to extended wildcards in 4DOS :-)
DIR can sort the files according to date and time, or name, or, in this case, extension. Direct that to a file (or get your input through a pipe from the CON device directly), parse out the numeric extension, and add 1: The command
DIR /A:-d /B /O:-e *.[0-9][0-9][0-9]
will display only files (no dirs) without header or footer sorted in descending order with numerical extensions in the range from .000 to .999. The following
DIR /A:-d /B /O:-e *.[0-9][0-9][0-9] | set n=%@EXT[%@LINE[CON,0]]
extracts the extension from the first line of CON and will give you the next extension in variable %n.
104) How do I run the latest executable from the default directory?
A nice way to select an executable file in the current directory, in this case ordered by date, is
DIR /B /O:-d *.exe;*.com;*.bat;*.btm | %=
which displays all executable files ordered by date (youngest first) in a nice menu window for your selection by cursor key (that's what %@SELECT does) and can be nicely concatenated to an alias.
To really blindly (!) run the latest executable, use
DIR /B /O:-d *.exe;*.com;*.bat;*.btm | %= %@LINE[CON,0]
105) How can I determine if ANSI.SYS is loaded?
IF %_ANSI == 1 ...
106) How do I get the last drive into an environment variable?
It already is in internal variable %_LASTDRIVE ...
107) How can I calculate the number of lines in a file?
You don't need to. It can be determined with internal function
108) Is it possible to save and later restore the command history?
Oh yes. 4DOS has a configurable command history buffer, and you can save it with
HISTORY > histfile
or append it with
HISTORY >> histfile
You can sort the histfile, delete dupes and reread it with
HISTORY /R histfile
109. Is it possible to change just one line of a file with a batch?
The short answer is: that depends...
... on a number of things. If we assume that it's a text file, then there are easy ways to change the first or the last line:
To add a first line, echo your text to a temp file, copy this temp file plus the oldfile to newfile, et voila.
To add a last line to oldfile, just echo your text using ">>" to append to that file.
To replace text in the middle, the best way would be to use an external tool.
Using 4DOS, you'd have to walk through each line of that file, using the %@LINE[file,n] function, copying unchanged lines to a new file, then add the changed new line, then add the rest of the oldfile lines to the new file. Doable, but not easy for the novice.
You can do such things in 4DOS even on the binary level on single bytes, and I have a few examples for this in my 4XBTM collection, but it would at least run to 10 or 20 lines :-) Ask me a concrete question for a specific file and I will show you how to do it.
110. Is it possible to delete lines by their linenumbers only?
You can determine the number of lines of a textfile by internal function @LINES[file], each individual line n by internal function @LINE[file,n], n starting with 0. So a batch to delete line n from a file would look like this:
DO n=0 to %@dec[%linetokill]
ECHO %@line[%infile,%n] >> outfile
DO n=%@inc[%linetokill] to %@lines[%infile]
ECHO %@line[%infile,%n] >> outfile
REN outfile %infile
This can be made quicker by using the @FILEOPEN, ...READ, ...WRITE, ..CLOSE functions, and by using SETDOS you can make it work with special characters (like those used for piping) too.
111. How can I tell what drive has been allocated by ramdrive.sys?
Prof. Salmi's solutions are all workable in 4DOS. If you want to determine this on another system, you'll have to take 3rd_ party ramdrives with other names into account. The only idea I can add is to use 4DOS' @TIMER function to time an action that would on a ramdrive be discernably faster that on any physical HD. That's not a trivial task, because eg. writing and reading a file would probably need a large file to see enough of a difference, and there is no data how large the ramdrive in question is. Then you have to consider the existence and influence of diverse caches that modern HDs and OSs employ. Whenever possible it is preferable by far to set a varibale (eg. SET ramdrive=1) in CONFIG.SYS when you load(high) the driver so you can check for that.
112. How can in insert a line in the middle of a file with a batch?
There are several possible solutions, and the question lacks the necessary info to discern which one is best or even relevant.
One solution is to use the batch solution from question 109 , add a line
ECHO This is the text for the inserted line >> outfile
between the 2 DO ... ENDDO loops. All remarks written there apply here too.
If you only have to insert an each time new line into a static, nonchanging file another, faster solution suggests itself: split the static file into 2 parts (using a text editor), part 1 containing the text before, part 2 containing the text after the insert. Now you can simply
COPY part1 outfile
ECHO This is the text for the inserted line >> outfile
COPY outfile + part2
to concatenate part1, inserted line and part2 to outfile.
113. What is difference between MS-DOS and various Windows batches?
This answer by Prof. Salmi is born out of a heated discussion in the alt.msdos.batch newsgroup. Some members there try to shun everything that does not fit a very narrow (but changing according to their own changing preferences) definition of a DOS batch, especially NT batch discussions.
4DOS users at least have the security that with 4NT they find a command processor under NT that is fairly compatible with 4DOS and shares its superior power.
114. Is it possible to display comments from the config.sys file?
I personally recommed CONFIX, a utility that can do more than echo from CONFIG.SYS. You can get it here.
115. Can I split a single command over multiple lines in a batch?
To make a very long command line more readable, you can tell 4DOS that the command line continues on the next line by ending the line with the escape char or its representational internal variable %=
116. How can I get yesterday's date into an environment variable?
Doing all sorts of date arithmetic is easy in 4DOS. For may commands you can enter date ranges:
COPY /[d-1,+0] *.* a:
Meaning: copy all the files that were changed yesterday to the floppy disk.
To get yesterday's date into a variable, convert current date to number of days since 1980, subtract one, convert back to date format, of course all with internal vars and functions:
SET yesterday=%@MAKEDATE[%@EVAL[%@DATE[%_DATE] - 1]]
Easy, isn't it?
Use 4DOS internal functions. Assuming "get" means putting the result in a variable, one solution would be
remembering 4DOS starts counting at 0 :-)
118) How to put the content of text file into a variable?
Under 4DOS you can parse a textfile into lines, the lines into words, the words into characters. This is essentially the same question as # 117
To get the oldest 3 files you can use this small btm:
DIR /b/o:d/a:-d * > %temp\dirfile.tmp
The output of a "blank" DIR command is piped into a file, then the first 3 (0-2) lines of that file are echoed to screen. To get the three latest files change the sorting order of the DIR command (/o.-d)
There is a very nice btm displaying the complete ascii chart in my 4XBTM collection: XASCII.BTM. You can switch between two pages, select a character and copy it to the Ctrl-Ins key for later use.
Assuming you want to execute TEST.BAT, which is in your path, you could execute
which will yield the desired result when %0 is expanded in your batch. Another way would be to use the internal variable %_batchname, which expands to the full path and filename of the current batch.
Just to make this a little bit more challenging here's the core of my XRCF.BTM (Recently Changed Files):
DIR /s/f/h/a/[d0]/[t-%1] *.*
You can call this from the command line with the number of minutes as parameter (%1) and it will show you all files changed within the given number of minutes in your current dir and its subdirs.
To test just one file if its filedate/time is less than an hour ago (even if you're just past midnight!) you could use the following 3-line btm (filename as parameter %1 in batch or alias):
SET fileage= %@EVAL[%@DATE[%@FILEDATE[%1]] * 28800 %=
SET now=%@EVAL[%@DATE[%_DATE] * 28800 %=
ECHO File is %@IF[%@EVAL[%now - %fileage] le 3600,younger,older] than 1 hour!
The 1st line (%= as the last entry on a line tells 4DOS that the line continues on the next line) determines the fileage in seconds (28800 in a day) since 01.01.1980.
This 2nd line determines the current date/time in seconds since 01.01.1980.
The 3rd line takes the 2 integers to determine if the fileage is less or more than 1 hour.
123) How I can (re)set the screen text and background colors?
The 4DOS solution is to use the vailable commands like CLS (with color parameters), COLOR, SCRPUT etc. which allow you to design your screen colors without cryptic ANSI escape sequences.
124) How do I get the echo status into an environment variable?
This will do the trick in 4DOS:
ECHO | INPUT %%_echo %+ SET _echo=%@WORD[2,%_echo]
THe output of the ECHO command is piped to the INPUT command, which sets our new %_echo variable, which is then shortened to the 3rd word (ON or OFF).
125) How can I delete all empty directories on a drive?
4DOS has the GLOBAL command, which will perform a given command in the current dir and all subdirs. Another possibility is to use FOR /R (recursive) for this purpose, but 4DOS' DEL command is powerful enough on its own:
DEL /a:d /sexy *
In the order of appearance: Delete only directories (attribute: d, you'd have to use a nonexisting dummy filename to delete without this.) recursing subdirs (/s), no error messages (/e, just there for the pun), remove empty subdirs (/x ) and say yes to all prompts (/y).
126) How can I put an = into an environment variable?
A real challenge ;-) 4DOS understands
127) How can I reverse a word or an entire line?
Now this one is real fun to do in 4DOS. I have written batches to produce all possible character combinations of a given name, produce all possible words of a given length (remember the story "All the Names of God" by Arthur C. Clarke?) and to mimic the monkey hammering the keys to eventually produce all the works of Shakespeare. To fulfill this special requirement, you could use
INPUT Enter your text: %%text
IFF "%text" NE "" THEN
SET text=%@REPLACE[ ,%@CHAR,%text]
DO n=%@DEC[%@LEN[%text]] TO 0 BY -1
SET text=%@REPLACE[%@CHAR, ,%text]
which does the following: it gets the text to reverse from the user and echos a blank line. It then checks for user abort (%text would not exist). A space in the variable %text would produce unwanted results, so the batch replaces all "soft" spaces with "hard" (ascii char 255) spaces. Now it echos the variable %text from last to first character on the same line. At last it replaces the hard spaces with soft spaces and you can continue to use the variable %text.
Note that this works only if there are no characters with special meaning in the %text variable (since we get our input via the INPUT command, none are possible here). If you derive the %text variable by some other means, however, SETDOS /X might be used to guard against percent, redirection, pipe and escape characters.