Welcome to The Tech 
Guide
Google
 
Web www.thetechguide.com
Geeks with attitude
Navigation
  • Home
  • How-To's
  • Tweaks
  • Hardware
  • Software
  • Games
  • Our Picks
  • Downloads
  • FAQ's
  • Forum
  • Chat
  • Tech Deals
  • Links
  • Email

  • Site News
    Our Black Friday section is now online! Click here to check it out.

    Active Discussions
    [an error occurred while processing this directive]


      

    Tutorial on Basic Windows 2000 DOS

      This Section Will Cover
    • 00. What a file is under win enviroment
    • 01. What a variable is in %win2k% batch and how to create them.
    • 02. What echo echo. @echo off does.
    • 03. What operators like > and >> and | do.
    • 04. What a ::comment is.
    • 05. What & does and how to use it &::creatively.
    • 06. What 'DIR' and 'SORT' is and does
    • 07. What a * and a ? mean to the DOS shell.
    • 08. What GOTO _is when used with :_labels, also using PING to create a delay.
    • 09. What if "statements"=="are and what they do".
    • 10. What a basic "for" loop is/does.
    • 11. How to use low interger values with variables.
    • 12. How to parse strings into substrings.
    • 13. How to echo non-echoable characters.
    • 14. How to pass %arguments to a .bat file.
    • 15. Summary

    Ok, the FOR loop. Although this is an extremely primitive FOR loop that win2k has, it can be very daunting to understand. But once you've got it, which might take time, you'll look back and say "Duh, that's simple". If you've never done anything like a FOR loop, you might be better off. I was doing FOR loops in C/C++ before in win2k .bat and I was like "What?!?!". I couldn't make heads or tails of it to be honest. If you know C, or done scripting on a unix system, what you're about to see is goofy. If not, well this is a good break in because the FOR loops in C or in bash or whatever are much easier, flexible, logical, and A LOT more free in terms of what you can do. It's not really the FOR loop that is goofy, its the damn shell that limits certain basic things. Like there is no escape character. An escape character only makes sense. What this is, is a character that escapes the system's way of handling a character and lets you use the character as a literal. What i mean by this is that, you know when you did DIR /B *.mp? Well, what if you want to use the characters of * or ?, what are you to do then? In programming languages and all shells besides win shells you can usually preceed the character with a \ to represent you want to use the character as it is without the shell's default method. \* or \? would let you search for those characters themselves. But you see, in windows you cant use those characters in file names. So the shell automatically thinks you don't need to process those characters PERIOD for ANYTHING you want to do...which is downright, I hate to use this word but it fits, stupid. I will cover a lengthy, but workable, way of getting around this stupid limitation later on. Ok let's start.

    Basically a FOR loop goes roughly like this...

    FOR variable IN (whatever) DO this_with variable
    FOR   %%i   IN  (*.*)   DO   echo    %%i
    NOTE: In .bat files you have to use %%. If you were typing this in live from the shell you would use 1 % The reason is yet again sort of goofy. It's because the % is used to reference variables. Like echo %fooy%. The system sees that fooy is surrounded by %'s so it knows to treat it as a variable and remove the %'s and reference the value. Strangely though, when you're typing in live commands not from a .bat but the shell itself, you still only use 1 % around variables. Got me, maybe I don't understand it right but it all seems goofy to me.

    Ok, make another .bat file and put the below in it....
    @echo off
    FOR %%i IN (*.*) DO echo %%i
    echo.
    echo  Press [ENTER] to exit
    pause >nul
    What you should see is a echo of all the files in the directory where the .bat is in your system. What this FOR loop will do is take all the variables in (*.*) and echo each one out. Now %%i is NOT all variables, in fact %%i is the last variable it found. (*.*) lists all files, same thing if you did DIR /B /A-D. Remember that /AD list all the directories, well when you preceed the D with a - that means NOT. So it lists everything that is NOT a directory. But /A-D is a DIR switch, let's get back to FOR loop.

    It goes through the loop as long as a file exists. %%i becomes the first file it finds. Then when it goes again %%i becomes the next file it finds, so on and so on until it finds no more files. So when the loop finally exits, %%i was the last file it found, not all the files it found. You can change this, with the cmd.exe in a manner where you could use %%i as if it was all files, but that goes beyond the scope of this tutorial because the easiest way to make this happen is by altering a registry key, and that is not what this is about.

    What lies within the ( ) in the FOR loop can pretty much be One of three things. But it's best understood as four things.
    1. A set of files�������(*.mp?)
    2. A command������������(DIR /B /A-D)
    3. A string of text�����("Hello Batch!")
    4. A set of arguments���(%1 %2 %3 %4 %5 %6 %7 %8 %9)
    In the above, number 4. the arguments can actually be any of the first three numbers depending on what the arguments are themselves. What I mean by this is that the syntax will remain the same, as in %1 %2 etc...but what those arguments are can vary. Each argument can be text, a file, or a command, but you probably will never see arguments being anything other than files. Due to the fact that it can be tricky to get white spaces (spaces and tabs are known as white spaces) and certain characters into arguments. Now when you pass in arguments, you dont use %1 %2 ... but when you read the arguments in a script after passing them into it, you use this method.

    Ok so we now know how to use DIR (or do we?).

    OK take the cdrom drive letter in your system, E: , F: or whatever it is, put a cd/dvd in the drive with files on it, and in a DOS shell type DIR /B E: or whatever you drive letter is.

    You should see a listing of all the directories and files in the root of the cd, remember root is the top most directory, like C:\ is root to your HDD. If you want to see what is in the subdirectories of of the directories on the cd, add the /S switch. DIR /B /S

    Ok now that you know what that does, let's explore the options of the FOR itself. Type FOR /? in a DOS window to see the options it has.

    Ok what you see is pretty lengthy, but not to worry, i'll make it simple for what we are going to use.
    FOR /F   - means you want to use a file as input
    FOR /F "usebackq tokens=* delims=_"  - means you want to use a file as input. usebakq means you want to enforce
                                           the routines more or less. And 
    tokens and delims means, well let's
                                           talk about that...
    Tokens and Delims go hand-in-hand. Delims is short for Deliminators. A deliminator is something that breaks someting into Tokens. For example, lets say you have the below string...

    Hello_my_handle_is_Space_Between

    Now the above is on string of text right? (a string means just a line of text, no hidden meaning). Ok let's say we want to get each word of the above string into seperate words, deliminators will do that for us. If we set our deliminator to equal an underscore delims=_ then the tokens get broken up like this...

    Token 1: Hello
    Token 2: my
    Token 3: handle
    Token 4: is
    Token 5: Space
    Token 6: Between

    With a delim of _ we get 6 tokens out of the string Hello_my_handle_is_Space_Between. I hope you understand this, this is as simple as I can make that :-).

    Ok notice the tokens=* in "usebackq tokens=* delims=_". Ok now tokens=* means I'm going to get all tokens that are in the string. Now by default, delims are set to white spaces (spaces and tabs), so I manaully set the delims=_ and now the only delim is a _. However, since I set tokens=*, I really don't need a delim at all. Since i'm going to get all tokens, what does it matter what my delim is? It doesn't. I'm getting all tokens regardless of what the delim may be. So if we use tokens=* we can just use "usebackq tokens=*" and nothing more. However, since deliminators are by default spaces and tabs, it won't break the string up into 6 tokens. Since we didn't specify a delims=_ it's going to use spaces and tabs, thus resulting in the same exact string of Hello_my_handle_is_Space_Between

    NOTE: I use usebackq because I'm used to using it, you can do it without usebackq, but it can possibly be better to usebackq regardless. So I suggest always to use it. However when you usebackq, you have to use different characters. Like backqoute, that is the key to the left of the number 1 and above the Tab key. It is on the same key as ~. When using usebackq you use a backqoute to surrond a command.

    Here is part of what FOR /? brings up in a shell...
    FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
    FOR /F ["options"] %variable IN ("string") DO command [command-parameters]
    FOR /F ["options"] %variable IN ('command') DO command [command-parameters]
    
        or, if usebackq option present:
    
    FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]
    FOR /F ["options"] %variable IN ('string') DO command [command-parameters]
    FOR /F ["options"] %variable IN (`command`) DO command [command-parameters]
    Ok, here is the FOR loop that can catalog a cd/dvd contents for you. Copy this and put it in your .bat and run it.
    Make sure your Drive letter is correct, im using E:\ for this example because it is my cdrom drive letter.
    @echo off
    FOR /F "usebackq tokens=*" %%i IN (`DIR /ON /B E:\`) DO ECHO %%i
    pause >nul
    Ok so that does nothing different than DIR /ON /B E:\ at all, same exact thing, however we can add things to this echo out...like variables.

    A nice way to get variables to add to this FOR loop would be to use SET /P. OK, SET /P actually halts the system and waits for you to type in something and hit the [ENTER] key.

    Ok now, find out the drive letter in your system and assign it to a variable. Change your script to look like the below script and run it after you have assigned the correct drive letter. I'm using E:\ still.
    @echo off
    DIR /B *.bat | FIND /I ".bat"&::using the /I switch with FIND makes it case insensitive
    SET CDROM=E:\
    echo  This pause is just so you can see that the pipe method
    echo  worked with DIR and FIND. More help on FIND with FIND /?
    echo.
    echo  Press [ENTER] to continue...
    pause >nul
    :_loopa
    CLS
    echo.
    echo.
    echo   Enter something now to prefix the output of your cdrom listing.
    echo.
    echo.
    SET prefix=&:: Notice I'm making sure prefix is unset to nothing at all
    SET /P prefix=
    IF "%prefix%"=="" GOTO _loopa
    echo.
    echo.
    SET suffix=&::
    :_loopb
    SET /P suffix=Enter a suffix for the output now:  &::suffix's prompt msg, not its value, nor ever will be
    IF "%suffix%"=="" GOTO _loopb
    echo.
    FOR /F "usebackq tokens=*" %%i IN (`DIR /ON /B %CDROM%`) DO ECHO %prefix% -: %%i  :- %suffix%
    echo.
    echo  Press [ENTER] to exit
    pause >nul
    In the above you notice that in SET /P suffix=Enter a suffix for the output now: and might be thinking that its value is already set. Well it's not. When you use SET /P you have the option of setting the prompt for it. This is not the value of suffix at all, and if you just hit enter without typing anything in then the variable has no value at all. At no point is the prompt going to be assigned to the variable. This prompt rarely comes in handy, but I found uses for it a couple times especially when how many lines can be displayed on the screen at one time came into concern.

    Also notice that I did SET prefix=&:: Notice I'm... just in case the variable prefix was already assigned. By doing this I assure myself of a loop if nothing is entered. If nothing is entered it performs GOTO _loopa Since I can not really do a IF statement on the contents of either prefix or suffix without knowing what they are, I SET them back to nothing. In a bigger script knowing exactly what a value is, to peform such a loop would be hard and tiring. suffix or prefix could have been anything before, so setting them back to "". let me know exactly what the value was.

    About the label, the label itself, should have a colon : in front of it, like :_loopb If you want to jump to that point you will have to use GOTO _loopb Notice there is no colon in front of the label name here. By rule the actual label is :_loopb but to GOTO it you don't use the colon :. Now in win2k you can use the colon. ie GOTO :_loopb, however this won't work on older platforms. Also, if you ever want to immediately exit a script with GOTO, there is a built-in label of :EXIT and :EOF. You're going to want to use :EXIT to exit out of a script, :EOF does the same thing but it goes to the End Of File. So to immeditely exit out of a script you can do GOTO :EXIT :EOF and :EXIT might be the same exact thing. I use :EXIT because I'm used to it. Both of them are for win2k and later, not anything older.

    If you wanted to use the actual code above to catalog, you could just put >> cat_file.txt on the end of the FOR loop and it would output everything to that file. However, I would suggest using a variable for the file name, like the below will output to a filename in the "my catalogs" directory...
    @echo off
    SET FILENAME="c:\my catalogs\cdvd cat.txt"
    SET CDROM=E:\
    MKDIR "C:\my catalogs" 2> nul
    DIR /B *.bat | FIND /I ".bat"&::using the /I switch with FIND makes it case insensitive
    echo  This pause is just so you can see that the pipe method
    echo  worked with DIR and FIND. More help on FIND with FINE /?
    echo.
    echo  Press a Key to continue
    pause >nul
    :_loopa
    CLS
    echo.
    echo.
    echo   Enter something now to prefix the output of your cdrom listing.
    echo.
    echo.
    SET prefix=&::
    SET /P prefix=
    IF "%prefix%"=="" GOTO _loopa
    echo.
    echo.
    SET suffix=&::
    :_loopb
    SET /P suffix=Enter a suffix for the output now:  &::suffix's prompt msg, not its value, nor ever will be
    IF "%suffix%"=="" GOTO _loopb
    echo.
    FOR /F "usebackq tokens=*" %%i IN (`DIR /ON /B %CDROM%`) DO ECHO %prefix% -: %%i  :- %suffix% >> %FILENAME%
    echo.
    echo  Press [ENTER] to exit
    pause >nul
    You might notice that when I declared my variable for the cdrom and for the filename, I used all capitals. This is good practice for variables that are fixed and whose values will not change. These variables will be CONSTANTS so by making them all UPPERCASE they are easier to find/alter if you have to debug, fix, or expand your code. Another reason they are all UPPERCASE is because by changing them you change them everywhere throughout your script. So just by changing this one variable, you might drastically change your entire script for better or for worse.

    Also if you're going to use spaces in your file names and directories (I surely hope you don't) you must surround them in "'s. This goes for directories too. Even if you don't use spaces it's good practice in win2k .bat to still do it.

    Also you see another command MKDIR This makes a directory named "C:\my catalogs". Remember if you're going to use spaces in filenames and/or directories you must use "'s. Now if the directory exists, it will give an error msg, but nothing bad will happen. However notice the 2>. You can put numbers before output >'s that represent the type of msg. The two most useful are 1> which basically is the samething as >, and the other is 2>nul This will redirect the error msg to nul. 2> is for errors more or less. Anyways, when you do MKDIR to create a directory, and the directory already exists, you may see a error msg unless you redirect the error output 2> to nul. By good practice anything you don't want seen by the user redirect it to >nul. If you're trying to redirect something to >nul and you see a error msg put a 2 infront of the >. It doesnt work always but alot of times it does.


    Click here to continue





    Questions? Ask in the forum or email me.

    For the Privacy Policy, click here.
      
    Past Articles
  • Build your own Apple Clone
  • AllofMP3 Review
  • Tutorial to Basic Windows 2000 DOS
  • Extracting and joining MPG2 files from SVCD
  • Modifying your Windows XP Boot Logo
  • Unlocking WinXP's setupp.ini
  • Making a Full Screen Bios Logo
  • Making your WinMe CD bootable
  • Auto-insert your Win9x serial
  • Auto-insert your Office2kserial
  • Why FedEx Sucks