From ts@uwasa.fi Mon Jan 31 00:00:00 2011
Subject: General information of this script tricks file package
Date: Mon, 31 Jan 2011 00:00:00
From: ts@uwasa.fi (Timo Salmi)

Assorted NT/2000/XP CMD.EXE Script Tricks            Mon 31-Jan-2011
=========================================
                                                 All rights reserved
                               Copyright (c) 2003-2011 by Timo Salmi

....................................................................
Prof. Timo Salmi   mailto:ts@uwasa.fi   ftp & http://garbo.uwasa.fi/
Hpage http://www.uwasa.fi/laskentatoimi/english/personnel/salmitimo/
Department of Accounting and Finance,  University of Vaasa,  Finland
Timo's  FAQ  materials  at   http://www.uwasa.fi/~ts/http/tsfaq.html
Digiphotos collection  at  http://lipas.uwasa.fi/ktt/lasktoim/photo/
Dense spam-kill procmail filtering with a public email key in effect
....................................................................

  +-----------------------------------------------------------+
  | This file belongs to TSCMD*.ZIP. Please do not distribute |
  | this 1CMDFAQ.TXT file separately! If you see this file    |
  | reproduced alone, please alert the SysAdmin immediately.  |
  +-----------------------------------------------------------+

 ftp://garbo.uwasa.fi/pc/link/tscmd.zip
 Useful NT/2000/XP script tricks and tips, T.Salmi
 Http link format http://garbo.uwasa.fi/pub/pc/link/tscmd.zip

If you prefer a web version of this FAQ section it is available at
http://www.netikka.net/tsneti/info/tscmd.php

Introduction
============

DESCRIPTION:  This  file contains assorted CMD.EXE script tricks for
Windows NT/2000/XP. The items are in no particular order.  There  is
some overlap in some of the items.

QUOTING:  You are free to quote brief passages from this 1CMDFAQ.TXT
file in your messages and postings provided you clearly indicate the
source.  If you do, the preferred pointer to me in such a connection
is "Prof. Timo Salmi of the University of Vaasa, Finland". Note that
the  contents,  as  well  as  the  index composition of the question
items, fully remains Timo Salmi's copyright.

WEB PAGES OR ANY OTHER REPRODUCTION: No part of this  material,  nor
its  index,  nor  the entire contents of this file may be reproduced
(in any language) on any World Wide  Web  pages  (with  the  natural
exception  of  straight  Usenet  news repository services) or in any
other electronic, physical or similar manner.

ASKING FOR ADVICE: Comments and corrections on the Usenet  news  are
solicited. Kindly avoid using email. Especially, if you wish to have
individual  script  programming  consultation,  please   post   your
question  to a Usenet newsgroup like news:alt.msdos.batch.nt . It is
much more efficient than asking me by email. I'd like to help, but I
am  very  pressed  for time. I prefer to pick the questions I answer
from the Usenet news. Thus I can answer publicly  at  one  go  if  I
happen  to  have  an  answer.  Besides,  newsgroups have a number of
readers who might know a better or an alternative answer.  Don't  be
discouraged,  though,  if  you  get  a reply like this from me. I am
always glad to hear from friendly fellow script file users. For more
on this aspect in a web page format see
  I need your advice with this programming problem
  http://lipas.uwasa.fi/~ts/garbinfo/garb3020.html

EMAIL FILTERED: Please be aware that because of the  huge  spam  and
other  problems on the Internet my email is strictly protected by an
elaborate filtering system requiring a password from non-whitelisted
users,  and discarding many sources. For those interested in further
details: http://lipas.uwasa.fi/~ts/info/spamfoil.html

CONTRIBUTORS: A FAQ-like collection always is more or less a product
of  collective  knowledge.  The initial origins of many of the ideas
are often ambiguous and  may  have  been  discovered  separately  by
several  authors.  Thus  a  collective  thanks  for  the  NT/2000/XP
scripting community is in order. Furthermore, at least the following
individuals  (and a number of knowledgeable non-listed posters using
aliases) have either directly contributed to or otherwise  knowingly
or  unknowingly  influenced  the  contents of this FAQ in a positive
manner:

  Allen, William
  Ballenger, Si
  Beckermann, Carsten
  Briscoe, Walter
  Calvert, Clay
  Davis, Ted
  Dunbar, Al
  Dye, Charles
  Grove, Harlan
  Hardy, Steve
  Kasal, Stepan
  Kleebauer, Herbert
  Lavedas, Tom
  Lawrence, Ritchie
  Meinhard, Klaus
  Plumeyer, Henning
  Prins, Robert
  Robyn, Phil
  Said, Marco Maier
  Smith, Gary L.
  Smith, Paul
  Stockton, John
  Stewart, Bill
  Suhovey, Alexander
  Tacke, Matthias
  Takashi, Ootani
  Vargo, Todd

SUBMITTING: Although feedback is welcome and this NT/2000/XP command
line script programming tricks and  files  collection  has  FAQ-like
features,  it  is not meant as a composition of collective knowledge
from various quarters. All the items in this collection are to be my
own  work. Thus you can't submit your own items into this collection
despite the feedback being welcome. (Feedback on the Usenet news  is
strongly  preferable  over  emailed  feedback.) However, there is an
item (#21) about additional sources of information.

REFERENCES/COMMENTS:  Many  items   contain   "References/comments:"
mainly  to  Usenet  news  postings stored at Google. These items are
there either as a historical  record  or  for  further,  interesting
readings. Nevertheless, this tscmd.zip NT/2000/XP CMD.EXE script FAQ
collection  is  a  self-contained  entity.  Please  note  that   the
reference  paths  to e.g. Google messages might have changed because
of the repository's system developments. I am not  going  to  second
guess  them.  My  originals  and  their Message-Ids will have to do.
(Find the message with the id 476f5d9d$0$14994$9b536df3@news.fv.fi )

OTHER RESOURCES: See item "21} Do you have  pointers  to  additional
script  material  and  tips?  Also see the included TSPROG.TXT file.
Furthermore, this collection has a sister FAQ  for  MS-DOS  batches.
Most  of  the  tricks there are directly applicable to Win..95/98/Me
and some of the items are  applicable  to  NT/2000/XP  command  line
script programming as well. The file in question is

 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
 Useful MS-DOS batch files and tricks, T.Salmi

DISCLAIMER: The author shall not be  liable  to  the  user  for  any
direct,  indirect  or consequential loss arising from the use of, or
inability to use, any information, program, script or file howsoever
caused.  No  warranty is given that the scripts, the programs or the
advice given will work under all circumstances. You  use  everything
at your own risk.
--------------------------------------------------------------------

Caveats
=======

The scripts in this FAQ have been tested on a Windows XP [Version
5.1.2600] Professional Edition, SP2, system, which adds some new
features to script commands and their parameters. Mostly, no attempt
has been or will be made to identify which features might be novel
compared to the earlier (factual) NT versions, or later Windows
operating systems. Thus there is no guarantee that all the solutions
are fully backwards, or forwards, compatible.

The code page used in testing and using the scripts has been 850.
The default language affects some of the script formulations and
outcomes such as the date and time formats. If you wish to emulate
this behavior put the following line near the top of your scripts:
  mode con: codepage select=850
Once you do it, it will stay in user-wide effect, until you change
it again. Cf. Item #11 for more details. Note that, depending on the
case, setting the codepage might not be enough. The Windows (Control
Panel) Regional Settings and the script particulars will have to
agree. Some customization may be required where either date, time,
currency or decimal conventions are involved.

The date/time format assumed is "31.01.2005 14:12:18". In other
words, the order is DD.MM.YYYY, the date separator is ".", the
timefields separator is ":" and the 24 hour format is assumed. If
yours differ either adjust the scripts where needed, or change your
defaults via
 Start
  Settings
   Control Panel
    Regional and Language Options
     Time:
     Short date:

Two very common external auxiliary programs are used in a few of the
solution versions presented. It is highly recommended anyway that
you obtain the following utilities:

GAWK.EXE A Pattern Scanning and Processing Language
 233923 Mar 25 1995 ftp://garbo.uwasa.fi/pc/unix/gawk2156.zip
 GNU awk text scanning and processing language
Be forewarned. If you use a different GAWK its syntax requirements
may slightly differ. See the example in item #6.

SED.EXE Stream Editor
 20368 Oct 1 1991 ftp://garbo.uwasa.fi/pc/unix/sed15x.zip
 HHSED executable, E.Raymond+D.Kirschbaum+H.Helman
 (Note, I use these older versions)

A few words about the philosophy of using gawk and sed solutions:
http://www.google.com/groups?selm=akkesb%24itn%40poiju.uwasa.fi
http://www.google.com/groups?selm=42612883%241_1%40news.dnainternet.net
However, some of these tricks might arise in a multi-user setting
where it is best to assume that only the native commands are
available. Therefore, the usage of any extra tools is avoided as the
only option as much as reasonable.

Visual Basic Script can be used to solve some, if not most of the
scripting problems. The same goes for QBASIC. However, not all the
items which could have been solved with Basic aided command line
scripts include the option. This is above all CMD.EXE scripting FAQ,
not a VBS or QBASIC FAQ.

A number of date-related items and routines are included.
Date-related standards and calculations can be quite involved.
Therefore, not all the refinements are fulfilled in the strictest
sense. To give one example, one item is about the date a certain
number of days ago. The effect of a potential daylight saving time
("summertime") shift is ignored. Thus the result might be off by one
day near the midnight under special circumstances. Likewise,
timezone differences are ignored. A reader requiring more accurate
knowledge is referred to the web pages by Dr. John Stockton which
can be found by starting at http://www.merlyn.demon.co.uk/index.htm#dat
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:00 2011
Subject: Script tricks index
Date: Mon, 31 Jan 2011 01:00:00
From: ts@uwasa.fi (Timo Salmi)

INDEX
=====

1}  How to get today's date elements into environment variables?
2}  On Windows XP how do you stop the script files from closing?
3}  How can I customize the Command Prompt Window with script commands?
4}  How can I test is it on MSDOS/Win3..9x/Me or NT/2000/XP?
5}  How do I get a fully qualified path name of my script?
6}  How does one get yesterday's date?
7}  How can I test if two files agree in size and datetime stamp?
8}  How do I find all the files made at or after YYYYMMDD HHMM?
9}  How can I suppress script error messages altogether?
10} How can I change the environment variable values within a FOR loop?
11} How do I retain my original code page in these scripts?
12} How can I rename all my .JPG files sequentially in a folder?
13} How do I get the current day of the week?
14} Help! My old batch files won't work since there is no choice.com
15} Is it possible to echo without linefeed like the Unix echo -n?
16} How can I get the time without having to press enter?
17} How can I avoid the potential "ECHO is off." in echoing %myvar%
18} How does one build re-usable script function modules?
19} How can one build a delay / sleep / wait procedure for a script?
20} Is is possible to right-justify numbers or words in a script?
21} Do you have pointers to additional script material and tips?
22} How do I capture the current folder name into a variable?
23} How do I get the n'th, the first and the last line of a text file?
24} How do I get the m'th item on the n'th line of a text file?
25} How can I quote with e.g. "> " an entire message?
26} How do I get the length of a string into a variable?
27} How can I remove all the blank lines from a text file?
28} How to convert a file written in IBM PC characters into LATIN1?
29} How do I drop the first two characters of a string, and so on?
30} Can one calculate the difference between two times in a script?
31} How many days ago was 31.12.2003? What date was it 100 days ago?
32} How can I convert a decimal number to binary, octal, hexadecimal?
33} How can I convert a binary, octal, hexadecimal into a decimal?
34} How can I remove the quote characters from a line?
35} How can I substitute the second field on each line of my file?
36} I start a program from my script and it hogs my command window.
37} How can I insert a line in the middle of a file with a script?
38} How can I set and test the errorlevel within a script file?
39} Is there a subroutine to convert a variable into uppercase?
40} How to get the number of and parse the arguments given to a script?
41} How can I create a zero-byte file? How do I test for it?
42} What is the subroutine for testing a filename for wildcards?
43} Is there a way of counting the number of files in a folder?
44} How do I get the first 68 columns from a text file?
45} How can I find out how many days old a file is?
46} Is a program available in the default folder or at path?
47} Is it possible to echo the redirection symbol in a script?
48} Why do some comment lines cause errors? What can I do about it?
49} I need to reverse a text file. How do I do that fairly quickly?
50} How do I get the position of a substring in a string?
51} How can I echo lines in different colors in NT scripts?
52} How can I enter a password into a variable without echoing it?
53} How can I quietly test if a disk device is ready or not?
54} How can I get the type of a disk device?
55} How to get the creation, last modified and last access of a file?
56} How to find and move more recent files from one folder to another?
57} How do I get a list of all my empty folders on c:\ ?
58} How do I best combine two quoted arguments into one quoted string?
59} How do I find if a folder exists? How about visible files in it?
60} How do I delete all but most recent 20 files in a folder?
61} How can one devise a command line calculator?
62} How can I compare within a script if two files are identical?
63} How to perform a command on each line of a file as an argument?
64} How to count the number of lines in a file, empty lines inclusive?
65} How do I add text in front and after each line in a text file?
66} How can I delete all the hidden Thumbs.db files from my system?
67} Is it possible to send a script variable value to the clipboard?
68} How can I test if a program already has been loaded?
69} How do I get the first, or the last, 400 lines of a file?
70} Calendar: What weekday was December 31, 2004?
71} How can I reboot my computer from a command line script?
72} Is it possible to use quotes as delims in for loops?
73} How can I convert a hexadecimal string into an ASCII string?
74} How can I compare two numbers that have decimals with IF?
75} How do I detect if an object is a file or a folder?
76} How do I create an empty file? How can I detect the empty files?
77} How do I list the files in \All Users\Desktop in the short format?
78} Is it possible automatically to record my logon times into a file?
79} How can I trim leading and trailing spaces?
80} How can I extract the last part of a path such as C:\ABC\DEF\GHI\?
81} Is there a script to capitalize all the words in a text file?
82} Why does echo 9>temp.txt fail while echo 10>temp.txt works?
83} How to archive files with a rotation of five latest generations?
84} How can I automate downloading files from an ftp-site?
85} How to test if a folder contains any files with long names?
86} How to put each line of a text file into an environment variable?
87} How can I create a four-digit random string?
88} How to convert DEC to HEX with a script file, and vice versa?
89} All of a sudden "echo." doesn't work any more. What's wrong?
90} How do I get the most recent file within a directory structure?
91} How do I get command-line reference help?
92} How do I play a sound or a tune from the command line?
93} How do I check if my script was given a parameter?
94} Can I send the script's output both to the screen and a log file?
95} How to perform an operation on all the filenames listed in a file?
96} Can one use a script to columnize a comma separated values file?
97} I need to remove duplicate entries from the output or a file.
98} How do I equate all zip files with the date of their latest file?
99} How do I "touch" a file to update its last modified datestamp?
100} How can I identify and copy the five latest files from a folder?
101} How to capture Volume Serial Number into an environment variable?
102} How can I extract the individual bits from a decimal byte?
103} How do I exit a loop by pressing a key?
104} How can one remove double quotes from a script variable?
105} How to detect whether or not a folder contains hidden files?
106} How to test whether a variable is a non-negative integer?
107} How to do non-trivial renaming such as IMG*.jpg to IMG_*.jpg?
108} How can I execute a script one line at a time to debug it?
109} How do I open e.g. three separate instances of notepad at one go?
110} Can I use a script to determine if a specific printer exists?
111} How can I detect if a folder is shared or not?
112} Help, an old program fails to run since I have no floppy drive.
113} How do I find all *.TXT files on the C: drive sorted by size?
114} How do I pick a file's lines that are three characters long?
115} How can I decompose the path to be one folder per line?
116} How do I get a list all the *.BAT files which are at path?
117} Is it possible to get the physical memory from the cmd?
118} How to handle irregular empty fields of a CSV file?
119} How can I remove any leading zeros from an unsigned integer?
120} How do I use AND/OR/XOR/NOT operators in an IF statement?
121} How do I make a simple reminder to pop up on the desktop?
122} How to list files present in folder A but not in folder B?
123} How to test if a file is in a folder or below two or more times?
124} How do I find files which do NOT contain the search string?
125} How do I get the age of a file? Or of the files in a folder?
126} How do I grep for a line with a tab?
127} How can I pad leading zeros or like to a variable?
128} How to prevent SET /P input from entering the command history?
129} Is it possible to stop and reset the print spooler with a script?
130} How do I find and delete files which contain a specific text?
131} How to get the language of Windows XP in a script?
132} How to find out the next weekday given today's?
133} How do I get the current IP address, number and name?
134} How do I advance the dates of my certain JPG files by one year?
135} How do I get information about a file extension association?
136} How do I find out when my PC was last booted?
137} I need to resize a group of images from the command line.
138} How can I get the long name of a short-named file or folder?
139} How do I convert UNIX newlines to PC eolns? And vice versa?
140} How do I count how many times a word appears in my text file?
141} Why isn't the ! character always echoed as expected?
142} How to extract the filename from the end of an URL reference?
143} How do I get the current time zone in a script?
144} How do I parse the items from a path like C:\a\b\c\d ?
145} How to find out if WinXP SP2 is installed via a script?
146} Using delayed expansion for giving variable values as arguments
147} What was the time 100 minutes ago?
148} How to calculate the day-of-year number with a pure cmd script?
149} How to calculate a date's week number with a pure cmd script?
150} How can I extract the http and ftp URL:s from an HTML file?
151} Extract the lines of a text file from between to marker-lines?
152} How can I remove all !:s and &:s from a text file with a script?
153} How do I test if my Internet connection to an IP is working?
154} How do I remove leading zeros from a string with script only?
155} How can I use command-line to open a Windows Explorer Window?
156} How does one create a shortcut using the command-line?
157} How to get the count of words and the last word of a variable?
158} Why won't the statements within my if condition work properly?
159} How do I test that a name does not contain lowercase letters?
160} How do I get a list of all my folders with and sorted by size?
161} How do I test that the Windows Script Host is available?
162} Finding duplicate files in a directory tree.
163} How do I test and ensure that CRLF is the last char of my file?
164} How to concatenate (join/paste side by side) two files?
165} How do I get the date and time separators and the local formats?
166} Substituting spaces with underscores in a folder's file names.
167} How do I find out who is logged on the system?
168} How do I invoke Safely Remove Hardware using a cmd script?
169} How to set the time server from cmd and how to synchronize the clock?
170} How do I get the total size of a volume, not just the available space?
171} How do I get a list of all the PC's folders with the attributes indicated?
172} How to change and restore the title bar text of the command prompt?
173} How do I get the original GUI path since CLI's may be changed?
174} How to write a script to launch a URL invoking the default browser?
175} How do I get the current video display resolution?
176} How to get the rest of the command line parameters?
177} How can I retrieve the target of a shortcut into a variable?
178} How does one plug files' modified date/time into a set of file names?
179} How to replace an asterisk "*" in an environment variable?
180} I want to exit my script if it already has been run today.
181} How do I get the IP-names for a logfile containing the IP-numbers?
182} How do I protect a script, e.g. for a safe access of user passwords?
183} How do I get the fileurl of a local filename?
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:01 2011
Subject: 1) How get today's date elements into environment variables?
Date: Mon, 31 Jan 2011 01:00:01
From: ts@uwasa.fi (Timo Salmi)

The undisputed mother of all Command Line Interface (CLI) cmd.exe
questions. Asked in several formats, one of the most common being
"how can I augment the date (and even the time) to be a part of my
file's (or folder's) name?" This alternative question is practically
equivalent since the best first step is to get the date elements
into environment variables and then utilize those in the task.

The easiest and most portable solution across different country
configurations is simply to call DATET.CMD which comes as a part the
FAQ package tscmd.zip. That option utilizes Visual Basic scripting,
but you do not need to concern yourself with any of the details.
Running DATET.CMD will set for you the following environment variables
  DatetDD=
  DatetMM=
  DatetYY=
  DatetYYYY=
  DatetWkD=
  DatetMon=
  DatetHH=
  DatetMI=
  DatetSS=
Note: If you run DATET.CMD from within another CMD.EXE script, do not
forget to use CALL to invoke.

There is an alternative version DATEG.CMD in tscmd.zip which utilizes
UnxUtils GnuAWK instead of Visual Basic scripting. Else than that in
works exactly the same way.

But on to the actual FAQ:

Method 1a:
  @echo off & setlocal enableextensions
  ::
  :: The date presentation assumes DD.MM.YYYY (else customize)
  :: mode con: codepage select=850
  ::
  for /f "tokens=1-3 delims=./-" %%f in ("%date%") do (
    set today_=%%h%%g%%f
    set dd_=%%f
    set mm_=%%g
    set yyyy_=%%h)
  echo %today_%
  echo dd_=%dd_% mm_=%mm_% yyyy_=%yyyy_%
  ::
  :: Clean up for the next test (superfluous because of setlocal/endlocal)
  for %%v in (today_ dd_ mm_ yyyy_) do set %%v=
  endlocal & goto :EOF
The output could be e.g.
  D:\TEST>cmdfaq
  20040316
  dd_=16 mm_=03 yyyy_=2004

Method 1b: A slight variation of Method 1a. Kok Yong Lee posed the
following question in microsoft.public.win2000.cmdprompt.admin

"I was trying to setup a routine backup of my data with the day of
backup as the name of file. For example
 wzzip 24_03_2006.zip Z:\data\*.*
Currently DATE /t on my machine return "24/03/2006"
I been messing about with the ideas of using the | in order to
retrieve the results from "DATE /t" and then feed it to wzzip as
input by to avail. Any one care to shed some light on this?"

I'll give the custom code. Assume that DATE /T gives 24.03.2006
The outcome can differ between locales. (For an advanced option on
getting date format information see item #165.) But if the format is
that (or 24/03/2006) then
  @echo off & setlocal enableextensions
  :: Get the date elements, allow for three different separators
  for /f "tokens=1-3 delims=./-" %%f in ('date /t') do (
    set today_=%%h%%g%%f
    set dd_=%%f
    set mm_=%%g
    set yyyy_=%%h)
  ::
  :: Remove this mathod's potential trailing space from the year
  set yyyy_=%yyyy_:~0,4%
  ::
  :: An extra precaution which may be unnecessary
  :: See to it that days 1-9 will always have a leading zero
  set dd_=0%dd_%
  set dd_=%dd_:~-2%
  ::
  :: When you are sure, remove the echo precaution from the next line
  echo wzzip %dd_%_%mm_%_%yyyy_%.zip Z:\data\*.*
  endlocal & goto :EOF
Testing this script one will get
  C:\_D\TEST>cmdfaq
  wzzip 24_03_2006.zip Z:\data\*.*
Naturally, 20060324.zip would make more sense (sort better), but that
is beside the current issue.

Method 2:
  @echo off & setlocal enableextensions
  mode con: cp select=850>nul
  set dd_=%date:~0,2%
  set mm_=%date:~3,2%
  set yyyy_=%date:~6,4%
  echo dd_=%dd_% mm_=%mm_% yyyy_=%yyyy_%
  endlocal & goto :EOF
The output might be e.g.
  D:\TEST>cmdfaq
  dd_=16 mm_=11 yyyy_=2003
However, in this option one assumes that the day and the month
always are two digits long, i.e. a leading zero is present when
necessary. (For more on this see the code of method 1b and the
similar item #16 about the time.) At the same time note the
substring denotation syntax. It is %var_:~Start,Count% where the
Start commences at 0, not the perhaps more customary 1. I.e. the
index of the first character is 0.

If one wants to be hyper-careful, then first put the date into a
variable
  @echo off & setlocal enableextensions
  mode con: cp select=850>nul
  set date_=%date%
  set dd_=%date_:~0,2%
  set mm_=%date_:~3,2%
  set yyyy_=%date_:~6,4%
  echo dd_=%dd_% mm_=%mm_% yyyy_=%yyyy_%
  endlocal & goto :EOF

Method 3:
  @echo off & setlocal enableextensions
  for /f "tokens=5-8 delims=.-/ " %%a in (
    'echo.^|date^|find "current"') do (
    set dd_=%%a
    set mm_=%%b
    set yyyy_=%%c
    )
  echo dd_=%dd_% mm_=%mm_% yyyy_=%yyyy_%
  ::
  for /f "tokens=5-8 delims=.-/: " %%a in (
    'echo.^|time^|find "current"') do (
    set hh_=%%a
    set mn_=%%b
    set ss_=%%c
    )
  echo hh_=%hh_% mn_=%mn_% ss_=%ss_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  dd_=11 mm_=10 yyyy_=2006
  hh_=23 mn_=07 ss_=09

Octals are (confusingly) identified by a leading zero. Therefore
consider carefully when wish to have the leading zero and when you
might wish to drop it. For example, if you add at the end of the above
code
  set /a ssplus1_=%ss_%+1
you'll get
  C:\_D\TEST>cmdfaq
  dd_=11 mm_=10 yyyy_=2006
  hh_=23 mn_=07 ss_=09
  Invalid number. Numeric constants are either decimal (17),
  hexadecimal (0x11), or octal (021).

Method 4 (with Time):
  @echo off & setlocal enableextensions
  rem
  rem Method 4: (with time)
  rem
  rem Assuming locale dependent date format DD.MM.YYYY
  rem 24-hour time format H:MN:SS
  rem Else customize
  set date_=%date%
  set time_=%time%
  set yyyy_=%date_:~6,4%
  set mm_=%date_:~3,2%
  set dd_=%date_:~0,2%
  set mn_=%time_:~3,2%
  set hh_=%time_:~0,2%
  set hh_=0%hh_: =%
  set hh_=%hh_:~-2%
  echo %yyyy_%%mm_%%dd_%%hh_%%mn_%
  endlocal & goto :EOF

The output might be e.g.
 C:\_D\TEST>cmdfaq
 200803232042

The problem can also be solved with a Visual Basic Script (VBScript)
aided command line script. It is much more complicated, but it has
the advantage of being more stable, i.e. less region dependent than
the pure CMD.EXE solutions. With addition to the date elements also
the time elements are included for demonstration.
  @echo off & setlocal enableextensions
  ::
  :: Make a temporary folder
  if not exist c:\mytemp mkdir c:\mytemp
  ::
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo c:\mytemp\tmp$$$.vbs
  ::
  :: Call the command line script which the script host built
  call c:\mytemp\tmp$$$.cmd
  ::
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.vbs c:\mytemp\tmp$$$.cmd) do (
    if exist %%f del %%f)
  rmdir c:\mytemp
  ::
  :: Show the results
  echo Date by %%date%% %date%
  echo Time by %%time%% %time%
  echo dd_=%dd_%
  echo mm_=%mm_%
  echo yyyy_=%yyyy_%
  echo hh_=%hh_%
  echo mi_=%mi_%
  echo ss_=%ss_%
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Const ForReading = 1, ForWriting = 2, ForAppending = 8             'VBS
  Dim DateNow, TimeNow, fso, f                                       'VBS
  DateNow = Date                                                     'VBS
  TimeNow = Time                                                     'VBS
  Set fso = CreateObject("Scripting.FileSystemObject")               'VBS
  Set f = fso.OpenTextFile("c:\mytemp\tmp$$$.cmd", ForWriting, True) 'VBS
  f.WriteLine "@set dd_=" & Right(0 & DatePart("d", DateNow), 2)     'VBS
  f.WriteLine "@set mm_=" & Right(0 & DatePart("m", DateNow), 2)     'VBS
  f.WriteLine "@set yyyy_=" & DatePart("yyyy", DateNow)              'VBS
  f.WriteLine "@set hh_=" & Right(0 & DatePart("h", TimeNow), 2)     'VBS
  f.WriteLine "@set mi_=" & Right(0 & DatePart("n", TimeNow), 2)     'VBS
  f.WriteLine "@set ss_=" & Right(0 & DatePart("s", TimeNow), 2)     'VBS
  f.Close                                                            'VBS
An example of the output
  D:\TEST>cmdfaq
  Date by %date% 16.03.2004
  Time by %time%  8:27:15.47
  dd_=16
  mm_=03
  yyyy_=2004
  hh_=08
  mi_=27
  ss_=15
In the above "Whenever an expression is not a string, it is
converted to a String subtype". So we could as well have e.g.
Right("0" & DatePart("d", DateNow), 2)

A more concise presentation
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp.vbs
  echo FixedNow=Now>"%vbs_%"
  echo WScript.Echo Right(0 ^& Day(FixedNow), 2) ^&" "^& ^
                    Right(0 ^& Month(FixedNow), 2) ^&" "^& ^
                    Year(FixedNow) ^&" "^& ^
                    Right(0 ^& Hour(FixedNow), 2) ^&" "^& ^
                    Right(0 ^& Minute(FixedNow), 2) ^&" "^& ^
                    Right(0 ^& Second(FixedNow), 2) >> "%vbs_%"
  cscript //nologo "%vbs_%"
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq
  22 10 2006 12 57 26

Another way of writing a VBScript solution
  @echo off & setlocal enableextensions
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Day(Date)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set dd_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Right(0 ^& DatePart("d", Date), 2)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set dd_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Right(0 ^& DatePart("m", Date), 2)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set mm_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo DatePart("yyyy", Date)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set yyyy_=%%a
  ::
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Right(0 ^& DatePart("h", Time), 2)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set hh_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Right(0 ^& DatePart("n", Time), 2)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set mi_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Right(0 ^& DatePart("s", Time), 2)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set ss_=%%a
  ::
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo dd_=%dd_%
  echo mm_=%mm_%
  echo yyyy_=%yyyy_%
  echo hh_=%hh_%
  echo mi_=%mi_%
  echo ss_=%ss_%
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  dd_=03
  mm_=04
  yyyy_=2008
  hh_=19
  mi_=21
  ss_=07

>Q: Ok, fine and dandy. But how do I get the day of the week into an
environment variable?

This can be solved e.g. with G(nu)AWK as follows
  @echo
  for /f %%d in ('gawk "BEGIN{printf\"%%s\n\",strftime(\"%%A\")}"') do (
    set wd_=%%d)
  echo %wd_%
The output might be e.g.
  Sunday

>Q: Ok, but how about the number of the week?

It is up to seeing a G(nu)AWK documentation. In this case the
formatting argument is "V" instead of the "A". For better backwards
compatibility, let's use an alternative trick for putting the
value into the environment variable.
  gawk 'BEGIN{printf"@set wk_=%%s\n",strftime("%%V")}'>"%temp%\tmp$$$.bat"
  for %%c in (call del) do %%c "%temp%\tmp$$$.bat"
  echo The week number is = %wk_%
  set wk_=
Note that there are different week number options and standards. See
item #70. Also see item #149 for code alternatives.

>Q: Ok, but how about the number of the day (1-366)?
Using VBScript
  @echo off & setlocal enableextensions
  :: Make a temporary folder
  if not exist c:\mytemp mkdir c:\mytemp
  :: Build a Visual Basic Script
  findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo c:\mytemp\tmp$$$.vbs
  :: Call the command line script the script host built
  call c:\mytemp\tmp$$$.cmd
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.vbs c:\mytemp\tmp$$$.cmd) do if exist %%f del %%f
  rmdir c:\mytemp
  :: Show the result
  echo Day Number dn_=%dn_%
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Const ForReading = 1, ForWriting = 2, ForAppending = 8              'VBS
  Dim DateNow, fso, f                                                 'VBS
  DateNow = Date                                                      'VBS
  Set fso = CreateObject("Scripting.FileSystemObject")                'VBS
  Set f = fso.OpenTextFile("c:\mytemp\tmp$$$.cmd", ForWriting, True)  'VBS
  f.Write "@set dn_=" & DatePart("y", DateNow)                        'VBS
  f.Close                                                             'VBS

Alternatively, much more concisely
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo DatePart("y", Date)
  for /f %%n in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set dn_=%%n
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo Day Number dn_=%dn_%
  endlocal & goto :EOF

An output example:
  C:\_D\TEST>echo %date%
  23.05.2006
  C:\_D\TEST>cmdfaq
  Day Number dn_=143

Consider an application needing today's date. Say we wish to find
all the files made today in a folder:
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%f in ("c:\mytest\*.*") do (
    echo "%%~tf" | find "%date%" > nul
    if !errorlevel! EQU 0 echo %%~tf %%~zf "%%~ff"
    )
  endlocal & goto :EOF
The output could be e.g.
  C:\MYTEST>cmdfaq
  23.05.2006 06:51 216 "C:\MYTEST\CMDFAQ.CMD"

Incidentally, for demonstration, that can be written with an
alternative syntax, not needing the enabledelayedexpansion
  @echo off & setlocal enableextensions
  for %%f in ("d:\bas\*.*") do (
    echo "%%~tf" | find "%date%" > nul && echo %%~tf %%~zf "%%~ff"
    )
  endlocal & goto :EOF
or, finding the files NOT made today
  @echo off & setlocal enableextensions
  for %%f in ("c:\mytest\*.*") do (
    echo "%%~tf" | find "%date%" > nul || echo %%~tf %%~zf "%%~ff"
    )
  endlocal & goto :EOF
For more on the conditional processing symbol || see (give the
command)
 hh ntcmds.chm::/ntcmds_shelloverview.htm

Back to getting the date and time. An advanced script method. Note,
however, that the WMIC (Windows Management Instrumentation
Command-Line Utility) is only available since XP, and might require
special privileges.
  @echo off & setlocal enableextensions
  for /f "tokens=* skip=1" %%i in ('wmic OS Get LocalDateTime') do (
    set LocalDateTime=%%i)
  echo LocalDateTime: %LocalDateTime%
  ::
  set year_=%LocalDateTime:~0,4%
  set month_=%LocalDateTime:~4,2%
  set day_=%LocalDateTime:~6,2%
  set hour_=%LocalDateTime:~8,2%
  set minute_=%LocalDateTime:~10,2%
  set second_=%LocalDateTime:~12,2%
  set sec100_=%LocalDateTime:~15,3%
  set tz_=%LocalDateTime:~21,5%
  set tz_=%tz_: =%
  ::
  echo year_    %year_%
  echo month_   %month_%
  echo day_     %day_%
  echo hour_    %hour_%
  echo minute_  %minute_%
  echo second_  %second_%
  echo sec100_  %sec100_%
  echo tz_      %tz_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  LocalDateTime: 20060806213955.468000+180
  year_    2006
  month_   08
  day_     06
  hour_    21
  minute_  39
  second_  55
  sec100_  468
  tz_      +180.

A reasonably locale-independent date elements' extraction with XP
cmd.exe with no third-party utilities involved:
  @echo off & setlocal enableextensions
  ::
  :: Still debugging?
  set debug=true
  ::
  :: Get the date from the first line of the date command
  for /f "tokens=2,5 delims= " %%a in ('echo.^|date') do (
    if not defined date_ set lang_=%%a
    if not defined date_ set date_=%%b
    )
  if defined debug echo %lang_%
  if defined debug echo %date_%
  ::
  :: Get the date format from the first line of the date command
  for /f "tokens=5 delims= " %%a in ('echo.^|date') do (
    set dateform_=%%a
    )
  if defined debug echo %dateform_%
  ::
  :: Local, but not that local that it is not English
  if not "%lang_%"=="current" (
    echo Error: The OS is not in English
    goto :EOF
    )
  ::
  :: Get the order of the date information
  set field1=%dateform_:~1,2%
  set field2=%dateform_:~4,2%
  set field3=%dateform_:~7,2%
  if defined debug echo %field1% %field2% %field3%
  if defined debug echo.
  ::
  :: Test and set according to the date format order
  :: dd-mm-yy
  if "%field1%"=="dd" (
    set day_=%date_:~0,2%
    if "%field2%"=="mm" (
      set month_=%date_:~3,2%
      set year_=%date_:~6,4%
      )
    )
  :: mm-dd-yy
  if "%field1%"=="mm" (
    set month_=%date_:~0,2%
    if "%field2%"=="dd" (
      set day_=%date_:~3,2%
      set year_=%date_:~6,4%
      )
    )
  :: yy-mm-dd
  if "%field1%"=="yy" (
    set year_=%date_:~0,4%
    if "%field2%"=="mm" (
      set month_=%date_:~5,2%
      set day_=%date_:~8,2%
      )
    )
  :: yy-dd-mm
  if "%field1%"=="yy" (
    set year_=%date_:~0,4%
    if "%field2%"=="dd" (
      set day_=%date_:~5,2%
      set month_=%date_:~8,2%
      )
    )
  ::
  :: Display the result
  if not defined day_ (
    echo Error: Unidentified date format
    goto :EOF
    )
  echo day_=%day_%
  echo month_=%month_%
  echo year_=%year_%
  endlocal & goto :EOF

The output might be e.g.
C:\_D\TEST>cmdfaq
  29.01.2007
  (dd-mm-yy)
  dd mm yy
  day_=29
  month_=01
  year_=2007

If one has a UNIX-port date (let's call it unxdate for distinction) we
can have
  @echo off & setlocal enableextensions
  for /f %%a in ('unxdate "+%%Y%%m%%d"') do (
    set date_=%%a)
  echo date_=%date_%
  for /f %%a in ('unxdate "+%%H%%M%%S"') do (
    set time_=%%a)
  echo time_=%time_%
  for /f %%a in ('unxdate "+%%Y%%m%%d%%H%%M%%S"') do (
    set datetime_=%%a)
  echo datetime_=%datetime_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  date_=20081007
  time_=125955
  datetime_=20081007125955

There is another Visual Basic Script (VBScript) aided command line
script solution based on the List the Local Time code in the Microsoft
TechNet Script Repository. It requires at least XP.
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  for /f "tokens=1-6 delims= " %%a in ('cscript //nologo "%vbs_%"') do (
    set yyyy_=%%a
    set mm_=%%b
    set dd_=%%c
    set hh_=%%d
    set mn_=%%e
    set ss_=%%f)
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  echo yyyy_=%yyyy_%
  ::
  set mm_=0%mm_%
  set mm_=%mm_:~-2%
  echo mm_=%mm_%
  ::
  set dd_=0%dd_%
  set dd_=%dd_:~-2%
  echo dd_=%dd_%
  ::
  set hh_=0%hh_%
  set hh_=%hh_:~-2%
  echo hh_=%hh_%
  ::
  set mn_=0%mn_%
  set mn_=%mn_:~-2%
  echo mn_=%mn_%
  ::
  set ss_=0%ss_%
  set ss_=%ss_:~-2%
  echo ss_=%ss_%
  ::
  endlocal & goto :EOF
  '
  'The Visual Basic Script 'VBS
  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 'VBS
  Set colItems = objWMIService.ExecQuery("Select * from Win32_LocalTime") 'VBS
  For Each objItem in colItems 'VBS
    WScript.StdOut.Write     objItem.Year &   " " 'VBS
    WScript.StdOut.Write     objItem.Month &  " " 'VBS
    Wscript.StdOut.Write     objItem.Day &    " " 'VBS
    Wscript.StdOut.Write     objItem.Hour &   " " 'VBS
    Wscript.StdOut.Write     objItem.Minute & " " 'VBS
    Wscript.StdOut.WriteLine objItem.Second 'VBS
  Next 'VBS

The output could be e.g.
  C:\_M>C:\_D\TEST\CMDFAQ.CMD
  yyyy_=2009
  mm_=04
  dd_=12
  hh_=07
  mn_=16
  ss_=12

Using JavaScript in WSH
  @echo off & setlocal enableextensions
  >  "%temp%\tmp.js" echo var D = new Date();
  >> "%temp%\tmp.js" echo D = (D.getFullYear()*100+D.getMonth()+1)*100+D.getDate();
  >> "%temp%\tmp.js" echo WScript.Echo(D);
  for /f %%a in ('cscript //nologo "%temp%\tmp.js"') do set YYYYMMDD=%%a
  for %%f in ("%temp%\tmp.js") do if exist %%f del %%f
  echo %YYYYMMDD%
  endlocal & goto :EOF

The output could be e.g.
  C:\_M>C:\_D\TEST\CMDFAQ.CMD
  20091230

References/Comments:
 http://www.google.com/groups?selm=c22iq3%241dm%2403%241%40news.t-online.com
 http://www.google.com/groups?selm=k9bxa7zebut0.y9wmsipnutlp.dlg%4040tude.net
 http://www.google.com/groups?selm=ehdse8%242mr6%241%40news.mtu.ru
 http://support.microsoft.com/kb/290216/en-us
 http://support.microsoft.com/kb/555314/en-us
 https://www.microsoft.com/technet/scriptcenter/scripts/os/dates/default.mspx
 http://www.google.com/groups?selm=epl874%242pur%241%40news.rtcomm.ru
 http://www.google.com/groups?selm=e9str2d7avc8foib2pkpcmlqi6835qkpt6%404ax.com
 http://www.merlyn.demon.co.uk/datefmts.htm
 http://www.google.com/groups?selm=Rq7gE4CspjOLFw3V%40invalid.uk.co.demon.merlyn.invalid
 http://www.google.com/groups?selm=hhh7tn%24302q%241%40adenine.netfront.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:02 2011
Subject: 2) On Windows XP how do you stop the script files from closing?
Date: Mon, 31 Jan 2011 01:00:02
From: ts@uwasa.fi (Timo Salmi)

If one runs a .cmd script file by clicking the icon of the script,
the window will close after the processing is completed.
Occasionally this may not be what the user wants.

Method 1: To keep the window open to see the results one can use:
  :: The body of the script with whatever task.
  :: Then
  pause
This will produce
  Press any key to continue . . .
The window will then close when a key is pressed.

You also might notice that some of my scripts included in this
collection have the concluding line
  if not defined cmdbox if defined PauseIfFromDesktop pause
The purpose of such a line is to prevent a script from immediately
closing on completion if called (clicked) from the desktop. This
allows you to view the results. However, this requires some special
arrangements.
 a) I have defined a PauseIfFromDesktop variable into my
    default environment:
      Right click: My Computer
      Choose Properties
      Choose Advanced
      Click "Environment Variables"
      For User variables click New
      Define PauseIfFromDesktop true
 b) See the "set cmdbox=true" spot in the next item.

Method 2: There is a more generic solution. Put as the very last
line of your script
  cmd
The window will remain open as was familiar from the Win3.x/95/98/Me
dosbox, and it will allow you to give further commands. To finally
close the window, type "exit". See the next item for utilizing the
"cmd" line in customizing a command line window to your liking.

Incidentally, for a quick glance in the Windows GUI (Graphical User
Interface) you can use in the CLI (Command Line Interface)
  winver

For more on the environment settings see item #173.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:03 2011
Subject: 3) How can I customize the Command Prompt Window with script commands?
Date: Mon, 31 Jan 2011 01:00:03
From: ts@uwasa.fi (Timo Salmi)

In fact the "cmd" method in the previous solution is the basis for
an answer to a similar question "How can I customize the Command
Prompt window with script commands?". The answer is that you first
give all the commands you want, then conclude with "cmd". And
naturally prepare a desktop icon to point to your script so that you
can open the window you have customized. Below is one example.

  @echo off
  echo +----------------------------------------+
  echo ^| CMDBOX.CMD CLI box by Prof. Timo Salmi ^|
  echo ^| Last updated Sat 15-November-2003      ^|
  echo +----------------------------------------+
  echo.
  ::
  :: Check about the Windows version
  if [%OS%]==[Windows_NT] goto _doit
  echo This script is for Windows NT/2000/XP/.. only.
  echo Or have you tampered with the predefined variables?
  pause
  goto _out
  ::
  :_doit
  :: Augment the Windows path (customize as appropriate) and show
  path c:\mytools;%path%
  path
  ::
  :: Select the fastest keyboard repeat-rate,
  mode con: rate=32 delay=1
  ::
  :: Select the code page Multilingual Latin 1
  mode con: codepage select=850
  ::
  :: Choose (e.g.) blue background and bright white foreground
  color 1F
  ::
  :: Make a home folder and go there
  if not exist c:\_h mkdir c:\_h
  c:
  cd c:\_h
  echo cd c:\_h
  ::
  :: Tag that we are in the Command Prompt Windows so that,
  :: if need be, scripts can be made aware if they are being
  :: called in the window instead a direct call from an icon
  set cmdbox=true
  ::
  :: Finally, start "a new instance of the command interpreter"
  cmd
  ::
  :: The exit in case something went wrong
  :_out

A script like this would display something like the following

  PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;...

  Status for device CON:
  ----------------------
      Lines:          1000
      Columns:        80
      Keyboard rate:  31
      Keyboard delay: 1
      Code page:      850

  Microsoft Windows XP [Version 5.1.2600]
  (C) Copyright 1985-2001 Microsoft Corp.

C:\_H>

If you just want to skip all that output, redirect to nul. For
example
  mode con: codepage select=850 >nul

To suppress the "Microsoft Windows" announcement, add switch /k to
the command interpreter calling line:
  cmd /k
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:04 2011
Subject: 4) How can I test is it on MSDOS/Win3..9x/Me or NT/2000/XP?
Date: Mon, 31 Jan 2011 01:00:04
From: ts@uwasa.fi (Timo Salmi)

This is one way how to test it:
  @echo off
  set is_nt=false
  echo.>nul & set is_nt=true
  :: Show the result
  echo is_nt=%is_nt%
It is based on the fact that in NT/2000/XP CMD.EXE "&" can be used
to separate multiple commands on one command line while in
MSDOS/Win3..9x/Me COMMAND.COM the "&" is not recognized.

Another, very similar option is based on the maximum length of a
label in the various systems:
  @echo off
  ::
  goto _123456789
  :_1234567
  set is_nt=false
  goto _tell
  :_123456789
  set is_nt=true
  goto _tell
  ::
  :_tell
  echo is_nt=%is_nt%
The output on an XP would be
  C:\_D\TEST>cmdfaq
  is_nt=true

A third option is the following. The most common. It assumes that
you have not tampered with the predefined system environment
variables for Windows XP. Their values can be changed by the user,
even if it is highly unrecommended.
  @echo off
  if [%OS%]==[Windows_NT] goto _xp
  :: whatever MSDOS..95/98/ME-syntax commands
  goto _end
  :_xp
  :: whatever NT/2000/XP-syntax commands
  :_end

A more specific alternative testing for XP in particular is the
following
  @echo off
  set is_xp=false
  ver|find "Microsoft Windows XP"
  if %errorlevel% EQU 0 set is_xp=true
  echo is_xp=%is_xp%
  set is_xp=
The output on an XP could be e.g.
  C:\_D\TEST>cmdfaq
  Microsoft Windows XP [Version 5.1.2600]
  is_xp=true
The solution has the added advantage that one can build a more
comprehensive identification on this alternative if one first maps
what the various Windows or MS-DOS versions will return for VER.

For a different, comprehensive identification of the particular
Windows_NT category, search http://www.commandline.co.uk/lib/treeview/index.php
by Ritchie Lawrence for the GetOS function.

James Pang wrote:
> I want to use below command to set the output string of find into
>  variable 'v' ver | find "Windows" | set /p v=
> but it doesn't work!!! anybody has any idea?

My response: That is a problem that is a superficially easy
  @echo off & setlocal enableextensions
  if [%OS%]==[Windows_NT] echo NT/2000/XP...
  for /f "tokens=2 delims=[]" %%v in ('ver') do set ver_=%%v
  echo %ver_%
  endlocal & goto :EOF
Which would give e.g.
  C:\_D\TEST>cmdfaq
  NT/2000/XP...
  Version 5.1.2600

However, that is somewhat of a circular deduction. We already have
advance knowledge what the OS is when using the above! Note that
'ver' output fields can differ between Windows versions. The more
fundamental question is how does one generally find out in a script
which OS? That problem has been tackled by Ritchie Lawrence in
 http://www.commandline.co.uk/lib/Batch%20Function%20Library/System%20Functions/GetOS.html

Here is my rendition, partly incomplete and (naturally) not tested for
all the OSes.
  @echo off
  set my_os=
  ::
  echo Test|find "Fail">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Pre MS-DOS 6.0
  if not "%my_os%"=="" goto _show
  ::
  ver|find "6.22">nul
  if errorlevel 0 if not errorlevel 1 set my_os=MS-DOS 6.22
  ::
  ver|find "Windows 95.">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Windows95
  ::
  if not "%OS%"=="Windows_NT" goto _show
  ::
  net config workstation|find /i "Software version"|find "NT40">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Windows NT 4.0
  ::
  net config workstation|find /i "Software version"|find "2000">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Windows 2000
  ::
  net config workstation|find /i "Software version"|find "2002">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Windows XP
  ::
  net config workstation|find /i "Software version"|find "2003">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Windows 2003
  ::
  ver|find " 6.">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Vista
  ::
  net config workstation|find /i "Software version"|find "Ultimate">nul
  if errorlevel 0 if not errorlevel 1 set my_os=Windows 7
  ::
  :_show
  if "%my_os%"=="" set my_os=Unknown
  echo %my_os%
  for %%v in (my_os) do set %%v=
The output could be e.g.
  C:\_D\TEST>cmdfaq
  Windows XP

Another option:
  @echo off & setlocal enableextensions
  set xp_=
  systeminfo|find "Microsoft Windows XP">nul
  if %errorlevel% EQU 0 set xp_=true
  if defined xp_ (
    echo XP
    ) else (
    echo Not XP)
  endlocal & goto :EOF

Or
  @echo off & setlocal enableextensions
  for /f "tokens=2 delims=:" %%a in (
    'systeminfo^|find /i "OS Name:"') do (
    set osname_=%%a)
  for /f "tokens=* delims= " %%a in (
    'echo %osname_%') do set osname_=%%a
  echo %osname_%
  endlocal & goto :EOF
The output e.g.
  C:\_D\TEST>cmdfaq
  Microsoft Windows XP Professional

Or
  @echo off & setlocal enableextensions
  ::
  :: Get the Operating System
  for /f "tokens=2,*" %%i in (
  'reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName^
    ^| find "REG_SZ"') do set prod_=%%j
  echo.%prod_%|find "Microsoft Windows XP">nul
  if %errorlevel% EQU 0 set xp_=true
  if defined xp_ (
    echo XP
    ) else (
    echo Not XP)
  endlocal & goto :EOF

A VBScript-aided solution:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  for /f "tokens=*" %%a in ('cscript //nologo "%vbs_%"') do set osName_=%%a
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  echo osName_=%osName_%
  ::
  endlocal & goto :EOF
  '
  'The Visual Basic Script 'VBS
  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 'VBS
  Set colOSes = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem") 'VBS
  For Each objOS in colOSes 'VBS
    Wscript.Echo objOS.Caption 'VBS
  Next 'VBS

The output could be e.g.
  C:\_M>C:\_D\TEST\CMDFAQ.CMD
  osName_=Microsoft Windows XP Professional

Incidentally, for a quick glance in the Windows GUI (Graphical User
Interface) you can use in the CLI (Command Line Interface)

winver

--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:05 2011
Subject: 5) How do I get a fully qualified path name of my script?
Date: Mon, 31 Jan 2011 01:00:05
From: ts@uwasa.fi (Timo Salmi)

At the command prompt enter "FOR /?". There look for the information
on the substitution of FOR variable references. In this particular
case you would use the "%~fI". Utilize the fact that the unexpanded
name of the script called will be in the parameter %0. Let's test it
  @echo off
  set fullnam_=%~f0
  echo %fullnam_%
  set fullnam_=
The output could be e.g.
  C:\_D\TEST>cmdfaq
  C:\_D\TEST\CMDFAQ.CMD
Note that the name might contain spaces after the expansion even
when the plain filename might not. So you may need to enclose
"fullnam_" into quotes, if you use it.

Let's also see what the other variable expansions provide. The full
name of our test file this time is "C:\_D\TEST\Testing for the FAQ.CMD"
  @echo off & setlocal enableextensions
  echo %%~f0 %~f0
  echo %%~d0 %~d0
  echo %%~p0 %~p0
  echo %%~n0 %~n0
  echo %%~x0 %~x0
  echo %%~s0 %~s0
  echo %%~a0 %~a0
  echo %%~t0 %~t0
  echo %%~z0 %~z0
  endlocal & goto :EOF

The output might be something like this:
  C:\_D\TEST>"Testing for the FAQ.CMD"
  %~f0 C:\_D\TEST\Testing for the FAQ.CMD
  %~d0 C:
  %~p0 \_D\TEST\
  %~n0 Testing for the FAQ
  %~x0 .CMD
  %~s0 C:\_D\TEST\TESTIN~1.CMD
  %~a0 --a------
  %~t0 29.03.2008 08:09
  %~z0 238

Another demonstration of the expansion is
  @echo off
  for %%f in (*.*) do echo %%~ff
It includes the full path into the "bare" default folder list.
The output might be something like this:
  C:\MYSCRIPT\XTOOLS\CMDBOX.CMD
  C:\MYSCRIPT\XTOOLS\FORFILES.EXE
  C:\MYSCRIPT\XTOOLS\HOMMAG.CMD
  C:\MYSCRIPT\XTOOLS\TEST.CMD
  C:\MYSCRIPT\XTOOLS\XPNEW.CMD
  C:\MYSCRIPT\XTOOLS\XPNEW1.CMD
  C:\MYSCRIPT\XTOOLS\XPTD.CMD
  C:\MYSCRIPT\XTOOLS\XPTDSUB.CMD
  C:\MYSCRIPT\XTOOLS\XPTODAY.CMD
  C:\MYSCRIPT\XTOOLS\XUNSUBST.CMD

If you use the following, the output will be exactly the same (again,
no quotes in the output)
  @echo off
  for %%f in ("*.*") do echo %%~ff

Likewise, no quotes in the output when using
  @echo off
  for %%f in ("*.*") do echo %%f

The output might be something like this:
  CMDBOX.CMD
  FORFILES.EXE
  HOMMAG.CMD
  TEST.CMD
  XPNEW.CMD
  XPNEW1.CMD
  XPTD.CMD
  XPTDSUB.CMD
  XPTODAY.CMD

However, with
  @echo off
  for %%f in ("XPNEW.CMD") do echo %%f

The output will be (irrespective of the existence or not of such a file):
  "XPNEW.CMD"

Consider another for loop expansion demonstration, which shows a
subtle difference in the behavior of explicit-path versus wild-carded
references. Observe the difference in the need of the quote characters
in order to arrive at comparable outcomes.
  @echo off & setlocal enableextensions
  echo.
  echo for %%%%f in ("C:\_D\TEST\My test file.txt") do echo %%%%f
  for %%f in ("C:\_D\TEST\My test file.txt") do echo %%f
  echo.
  echo for %%%%f in ("C:\_D\TEST\*.txt") do echo "%%%%f"
  for %%f in ("C:\_D\TEST\*.txt") do echo "%%f"
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq

  for %%f in ("C:\_D\TEST\My test file.txt") do echo %%f
  "My test file.txt"

  for %%f in ("C:\_D\TEST\*.txt") do echo "%%f"
  "C:\_D\TEST\My test file.txt"
  "C:\_D\TEST\My test file2.txt"

Still a demonstration of the subtleties of explicit file names and
file names with wildcards.
  @echo off & setlocal enableextensions
  set tempdir_=C:\_M
  for %%f in (F-PROT.INI
              PS.DAT
              PS.SBK
              RANDSEED.BIN
              "My Scans.lnk"
              Thumbs.db
              ) do if exist "%tempdir_%\%%~f" echo del /p "%tempdir_%\%%~f"
  for %%f in ("%tempdir_%\Copy of *.JPG") do if exist "%%f" echo del /p "%%f"
  endlocal & goto :EOF
The output could be e.g.
  C:\_M>c:\_d\bas\cmdfaq
  del /p "C:\_M\PS.SBK"
  del /p "C:\_M\My Scans.lnk"
  del /p "C:\_M\Copy of 69010605.JPG"

Another demonstration. What will the following code output?
  @echo off & setlocal enableextensions
  for %%a in ("Hello World") do echo %%a
  for %%a in ("Hello World") do echo %%~a
  for %%a in ("*") do echo %%a
  endlocal & goto :EOF
The output:
  C:\_D\TEST>CMDFAQ
  "Hello World"
  Hello World
  My test file.txt
  My test file2.txt
Why? Because the wildcard matches all the files in the folder.

References/Comments:
 hh ntcmds.chm::/percent.htm
 http://www.google.com/groups?selm=uaiog0tc9rgjfus35i4um08bpjus3q7s9m%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:06 2011
Subject: 6) How does one get yesterday's date?
Date: Mon, 31 Jan 2011 01:00:06
From: ts@uwasa.fi (Timo Salmi)

Utilizing G(nu)Awk we can demonstrate
  @echo off & setlocal enableextensions
  gawk 'BEGIN{printf"%%s\n",strftime("%%x",systime()-24*60*60)}'
  set back_=1
  gawk 'BEGIN{printf"@set datewas_=%%s\n",^
    strftime("%%d.%%m.%%Y",systime()-%back_%*24*60*60)}'^
    >>"%TEMP%\tmp$$$.cmd"
  for %%f in (call del) do %%f "%TEMP%\tmp$$$.cmd"
  echo The date was %datewas_%
  endlocal & goto :EOF

The output will be something like
  Wed Nov 19 2003
  The date was 19.11.2003

As a side issue also notice continuing a line with the caret ^.

There is a catch. If one uses a more recent gawk then with that gawk
port (let's call it unxgawk) one has to adjust the syntax to
  @echo off & setlocal enableextensions
  unxgawk "BEGIN{printf\"%%s\n\",strftime(\"%%x\",systime()-24*60*60)}"
  set back_=1
  unxgawk "BEGIN{printf\"@set datewas_=%%s\n\",strftime(\"%%d.%%m.%%Y\",systime()-%back_%*24*60*60)}">>"%TEMP%\tmp$$$.cmd"
  for %%f in (call del) do %%f "%TEMP%\tmp$$$.cmd"
  echo The date was %datewas_%
  endlocal & goto :EOF

This task could also be performed using Zeller's congruence. It will
take some programming. External date to/from Julian date number
programs are utilized in the solution below
  @echo off
  ::
  :: Get and show today's Julian date number
  :: Requires DATE2NUM.EXE from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
  DATE2NUM /set > "%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  echo datenum_=%datenum_%
  ::
  :: Calculate yesterday's Julian date number
  set /a yesterday_=%datenum_% -1
  ::
  :: Convert it back into a date
  :: Requires NUM2DATE.EXE from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
  NUM2DATE %yesterday_% /set > "%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  echo dd_=%dd_% mm_=%mm_% yyyy_=%yyyy_%
  ::
  :: Clean up
  for %%v in (datenum_ yesterday_ dd_ mm_ yyyy_) do set %%v=
The output would be something like
  D:\TEST>cmdfaq
  datenum_=2452982
  dd_=7 mm_=12 yyyy_=2003

Yesterday date problem can also be solved with a Visual Basic Script
(VBScript) aided command line script
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  findstr "'VBS" "%~f0"|findstr /v "findstr" > tmp$$$.vbs
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo tmp$$$.vbs
  :: Call the command line script the script host built
  call tmp$$$.cmd
  :: Clean up
  for %%f in (tmp$$$.vbs tmp$$$.cmd) do if exist %%f del %%f
  :: Show the result
  echo %date%
  echo yd_=%yd_%
  endlocal & goto :EOF
  '
  Dim oShell                                                                  'VBS
  Set oShell = WScript.CreateObject ("WSCript.shell")                         'VBS
  oShell.run "cmd /c echo @set yd_=" & DateAdd("d",-1,Date) & " > tmp$$$.cmd" 'VBS

The output would be something like
  D:\TEST>cmdfaq
  31.01.2004
  yd_=30.01.2004

Or, more concisely
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" echo WScript.Echo DateAdd("d",-1,Date)
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%vbs_%"') do set yd_=%%a
  for %%f in ("%vbs_%") do if exist %%f del %%f
  :: Show the result
  echo %date%
  echo yd_=%yd_%
  endlocal & goto :EOF

Just for the sake of demonstration, even if not necessary for this
item in any way, the usage of usebackq
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" echo WScript.Echo DateAdd("d",-1,Date)
  for /f "usebackq tokens=* delims=" %%a in (
    `cscript //nologo "%vbs_%"`) do set yd_=%%a
  for %%f in ("%vbs_%") do if exist %%f del %%f
  :: Show the result
  echo %date%
  echo yd_=%yd_%
  endlocal & goto :EOF

Also see items #31 and #147. Also related the accompanying EDATE.CMD
and GDATE.CMD scripts.

References/Comments:
 http://www.google.com/groups?selm=4HHCtPLs78GAFwt8%40merlyn.demon.co.uk
 http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/569e6991b4af325e/4595b370fb03dc1f?hl=en&lr=&ie=UTF-8&rnum=1&prev=/groups%3Fselm%3Db2a353ab.0407051330.6d17beb9%40posting.google.com#4595b370fb03dc1f
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:07 2011
Subject: 7) How can I test if two files agree in size and datetime stamp?
Date: Mon, 31 Jan 2011 01:00:07
From: ts@uwasa.fi (Timo Salmi)

This one is rather simple given the features of XP CMD.EXE.
  @echo off
  ::
  setlocal
  :: Get the filenames (one way or the other)
  set file1_=%~1
  set file2_=%~2
  rem set file1_=c:\_d\bas\batfaq2.bat
  rem set file2_=c:\_f\xtools\xptd.cmd
  ::
  :: Check for existence
  for %%f in ("%file1_%" "%file2_%") do (
    if not exist %%f (
      echo File %%f not found
      goto :EOF))
  ::
  :: Get the filesizes and the datestamps
  for %%f in ("%file1_%") do set size1_=%%~zf
  for %%f in ("%file2_%") do set size2_=%%~zf
  for %%f in ("%file1_%") do set date1_=%%~tf
  for %%f in ("%file2_%") do set date2_=%%~tf
  ::
  :: Also get the full file names (optional)
  for %%f in ("%file1_%") do set file1_=%%~ff
  for %%f in ("%file2_%") do set file2_=%%~ff
  ::
  :: Demonstrate what we've got so far
  echo %date1_% "%file1_%" %size1_%
  echo %date2_% "%file2_%" %size2_%
  ::
  :: Do the comparison
  set same_=false
  if "%size1_%"=="%size2_%" if "%date1_%"=="%date2_%" set same_=true
  ::
  :: Display the results
  if /i "%same_%"=="true" (
    echo The file dates and sizes agree
    ) else (
    echo The file dates and/or sizes do not agree)
  endlocal
  goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq "KOE 2.CMD" "VBSFAQ2.VBS"
  12.09.2004 09:28 "C:\_D\TEST\KOE 2.CMD" 817
  06.10.2007 09:28 "C:\_D\TEST\VBSFAQ2.VBS" 4084
  The file dates and/or sizes do not agree

Also see Item #62.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:08 2011
Subject: 8) How do I find all the files made at of after YYYYMMDD HHMM?
Date: Mon, 31 Jan 2011 01:00:08
From: ts@uwasa.fi (Timo Salmi)

Let us start with the easier task of finding and copying all the
files made today. Be forewarned, though. It is slow.
  @echo off & setlocal enableextensions
  ::
  set TargetFolder=C:\Whatever
  if not exist "%TargetFolder%" (
    echo Target folder "%TargetFolder%" not found
    goto :EOF)
  ::
  :: Get the date elements (see FAQ Item #1)
  :: The date presentation assumes DD.MM.YYYY (else customize)
  for /f "tokens=1-3 delims=./-" %%a in ("%date%") do (
    set dd_=%%a
    set mm_=%%b
    set yyyy_=%%c)
  set dd_=0%dd_%
  set dd_=%dd_:~-2%
  set xcdate_=%mm_%-%dd_%-%yyyy_%
  ::
  :: Test the copying. When done, remove the test switch /L
  :: Customize the target s:\
  for /f "tokens=*" %%d in ('dir "C:\*.*" /s /b /a:-d-s-h') do (
    xcopy /L /p /v /f /d:%xcdate_% "%%~fd" "%TargetFolder%\"
    )
  endlocal & goto :EOF

Then lets move to the more demanding task of finding the files made
at or after YYYYMMDD HHMM
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Where to start from? Some options to customize!
  set MyRoot=%USERPROFILE%\My Documents
  set MyRoot=C:\_F
  if not exist "%MyRoot%\" (
    echo Start folder "%MyRoot%" not found
    goto :EOF)
  ::
  if not "%1"=="" goto _ask
  :: The usage help
  :: Note below the need of the escape character (^) because
  :: parentheses are special characters
  echo.
  echo Usage: %~f0 SinceDateAs:YYYYMMDD [SinceTimeAs:HHMN]
  echo.
  echo For example: %~f0 20031116 0900
  echo              %~f0 today 0900
  echo              %~f0 today ^(the time defaults to 00:00^)
  echo.
  echo Careful, minimal error checking!
  goto :EOF
  ::
  :_ask
  echo This might take some time.
  :_ask2
  set ask_=
  set /p ask_="Run anyway [Y/n]?"
  if /i "%ask_%"=="n" goto :EOF
  if not "%ask_%"=="" if /i not "%ask_%"=="y" goto _ask2
  ::
  :: Get today's date elements
  :: The date presentation assumes DD.MM.YYYY (else customize)
  set dd_=%date:~0,2%
  set mm_=%date:~3,2%
  set yyyy_=%date:~6,4%
  ::
  :: Process the user's parameters
  set cutdate_=%1
  if /i "%cutdate_%"=="today" set cutdate_=%yyyy_%%mm_%%dd_%
  if "%2"=="" (
    set cutime_=0000
    ) ELSE (
    set cutime_=%2)
  ::
  :: Do some trivial parameter checking (optional)
  set ParamError=
  if "%cutdate_:~7,1%"=="" set ParamError=true
  echo %cutdate_%|findstr "[^0-9]">nul
  if %errorlevel% EQU 0 set ParamError=true
  if "%cutime_:~3,1%"=="" set ParamError=true
  echo %cutime_%|findstr "[^0-9]">nul
  if %errorlevel% EQU 0 set ParamError=true
  if defined ParamError (
    echo Error in the parameters %cutdate_% %cutime_%
    goto :EOF)
  ::
  :: Traverse the folder trees
  if exist "%temp%\TODAY.DIR" del "%temp%\TODAY.DIR"
  echo Date     Time       Size Name
  for /f "tokens=*" %%f in (
    'dir "%MyRoot%\*.*" /s /b /-c /a:-d-s-h') do (
    call :ListFileIfSince "%%~ff"
    )
  ::
  :: Display the results optionally redirected to "%temp%\TODAY.DIR"
  sort "%temp%\TODAY.DIR"| more
  ::
  :: Delete the results file if you so wish
  del /p "%temp%\TODAY.DIR"
  ::
  endlocal & goto :EOF
  ::
  :: ====================================================================
  :: Subroutine: Get the file's information and compare the datetimestamp
  :ListFileIfSince
  setlocal enableextensions disabledelayedexpansion
  set filename_=%1
  for %%a in (%filename_%) do (
    set fdate_=%%~tf
    set fattr_=%%~af
    set fsize_=%%~zf
    )
  call :RightJustify10 %fsize_% fsize_
  for /f "tokens=1-5 delims=./-: " %%a in ("%fdate_%") do (
    set fdd_=%%a
    set fmm_=%%b
    set fyyyy_=%%c
    set fhh_=%%d
    set fmn_=%%e
    )
  if %fyyyy_%%fmm_%%fdd_% LSS %cutdate_% goto :EOF
  if %fyyyy_%%fmm_%%fdd_% EQU %cutdate_% if %fhh_%%fmn_% LSS %cutime_% goto :EOF
  >>"%temp%\TODAY.DIR" echo %fyyyy_%%fmm_%%fdd_% %fhh_%%fmn_% %fsize_% %filename_%
  endlocal & goto :EOF
  ::
  :: =========================================================
  :: Subroutine: Pad a string to always be ten characters long
  :RightJustify10 number_ return_
  setlocal enableextensions disabledelayedexpansion
  set number_=         %1
  set return_=%number_:~-10%
  endlocal & set "%~2=%return_%" & goto :EOF

It is easy to see that by suitably customizing the last "echo" line
you could perform many kinds of commands on those files. Or you
could first direct the output as a safety to yet another script file
for further inspection and editing. And so on.

The output might look something like this
  C:\_D\TEST>cmdfaq today 1000
  Date     Time       Size Name
  20080407 1020    1119035 "C:\_F\HAKEM\GARF\GARF_.ZIP"
  20080407 1023    1166358 "C:\_F\HAKEM\BERT\BERT_.ZIP"
  20080407 1048        970 "C:\_F\FHELP\TOBEDONE.TXT"
  20080407 1157      11115 "C:\_F\INF\TSCMDIDX.TXT"
  20080407 1157      33342 "C:\_F\INF\TSCMDNWS.TXT"
  20080407 2101     426766 "C:\_F\CMD\1CMDFAQ.TXT"
  C:\DOCUME~1\TS8C97~1.HUP\LOCALS~1\Temp\TODAY.DIR, Delete (Y/N)? y

One more thing. Consider the snippet
  for /f "tokens=*" %%f in (
    'dir "%MyRoot%\*.*" /s /b /-c /a:-d-s-h') do (
    call :ListFileIfSince "%%~ff"
    )
You might wish to browse a different set of folders. E.g. I might have
  for /f "tokens=*" %%f in (
      'dir "C:\_D\*.*"
      "C:\_E\*.*"
      "C:\_F\*.*"
      "C:\_G\*.*"
      "C:\_H\*.*"
      "C:\_L\*.*"
      /s /b /-c /a:-d-s-h') do (
    call :ListFileIfSince "%%~ff"
    )

Also see RECENT.CMD and RECENT.VBS scripts included in this FAQ
package.

References/Comments:
 http://www.google.com/groups?selm=c0b8pd%24nbr%2406%241%40news.t-online.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:09 2011
Subject: 9) How can I suppress script error messages altogether?
Date: Mon, 31 Jan 2011 01:00:09
From: ts@uwasa.fi (Timo Salmi)

To introduce, let's take the example of finding out which drives are
present and read, and which are not.
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%a in (A B C D E F G H I J K L M
              N O P Q R S T U V W X Y Z) do (
    dir %%a:\ 2>&1|findstr /b /i /r /c:" Volume in drive ">nul
    if !errorlevel! EQU 0 (
      echo Device %%a: found and ready
      ) else (
      echo Device %%a: not found or not ready)
    )
  endlocal & goto :EOF
The output e.g.
C:\_D\TEST>cmdfaq
  Device A: not found or not ready
  Device B: not found or not ready
  Device C: found and ready
  Device D: found and ready
  Device E: found and ready
  Device F: not found or not ready
  :
  Device Y: not found or not ready
  Device Z: found and ready

Compare that with what we would have with the two redirections
2>&1 and >nul omitted:
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%a in (A B C D E F G H I J K L M
              N O P Q R S T U V W X Y Z) do (
    dir %%a:\ |findstr /b /i /r /c:" Volume in drive "
    if !errorlevel! EQU 0 (
      echo Device %%a: found and ready
      ) else (
      echo Device %%a: not found or not ready)
    )
  endlocal & goto :EOF
The output could be
  C:\_D\TEST>cmdfaq
  The device is not ready.
  Device A: not found or not ready
  The system cannot find the path specified.
  Device B: not found or not ready
   Volume in drive C is SUPU_C
  Device C: found and ready
   Volume in drive D is SALMI_1GB
  Device D: found and ready
   Volume in drive E has no label.
  Device E: found and ready
  The system cannot find the path specified.
  Device F: not found or not ready
  :
  The system cannot find the path specified.
  Device Y: not found or not ready
   Volume in drive Z is SupuZip20080315
  Device Z: found and ready

Having observed the above, let's start from the basics. This is a
classic carryover from UNIX. First consider
  @echo off
  echo Customized pause, press the anykey ...
  pause>nul
The usual pause message goes to the nul bitbucket, and only the
customized message appears (actually before the pause).

When you type
  dir *.tex > texlist.dir
you'll get the folder listing into texlist.dir but if there are any
errors, then the error messages are forced on the standard output
device (the screen), not to textlist.dir, while the rest of the output
still goes there. You would have on the screen the message
  File Not Found

What if you do not wish to see that message, but redirect it to the
bit bucket. This is the syntax then
  dir *.tex > texlist.dir 2>&1
Since the test folder has no *.tex file, a file "File Not Found"
message is produced, but it is redirected to texlist.dir, not to the
screen.

Consider the following cryptic-looking script
  @echo off
  dir > nul 2>&1
It produces no output. Now why would one wish to do something like
that? ... Because, some commands return an errorlevel, and that is
what one really is after, as is seen from the example which this item
started with.

For example XCOPY returns exit codes as shown by the demonstration
below where "Y:" is a non-existent drive in the test.
  @echo off
  xcopy /v *.* Y: > nul
  for %%L in (5 4 3 2 1 0) do if errorlevel==%%L (
    set level_=%%L
    goto _tell
    )
  :_tell
  echo The errorlevel of the operation was %level_%
  set level_=

The output produced will be
  Invalid drive specification
  The errorlevel of the operation was 4
However, change the second line to
  xcopy /v *.* Y: > nul 2>&1
and the only output will be just
  The errorlevel of the operation was 4

Another example. Assume that there is no disk in the A: drive.
  dir a:
will produce
  The device is not ready.
However
  dir a:>nul 2>&1
will only produce a blank line, but not the error message.

Why 2>&1? Because the numeric equivalent of the STDERR is 2 and the
numeric equivalent of STDOUT handle is 1. This becomes more evident
if you do the following in phases
  dir NoSuchFile 2>stderr.tmp
The error message will be directed to stderr.tmp while the rest will
appear on the screen. Then enter
  dir NoSuchFile>out.tmp 2>&1
and all the output, the error message included, will go to out.tmp

This item was about suppressing error messages. Another way of
thinking is avoiding the errors, at least in easily expected
situations. Consider
 DIR "C:\_M\*.CMD"
which will produce
 File Not Found
if no *.CMD files are located in the folder C:\_M. This can be
avoided by instead using either
  if exist "C:\_M\*.CMD" dir "C:\_M\*.CMD"
or e.g.
  for %%f in ("C:\_M\*.CMD") do echo %%~tf %%~zf  "%%~ff"

Below is a demonstration how to play with stderr. The unraveling and
customizing to one's own potential task is left to the reader
  @echo off & setlocal enableextensions
  for %%f in (stderr.tmp tmp$$$.cmd) do if exist %%f del %%f
  set var_=
  ::
  dir cmdfaq.cmd 2>stderr.tmp
  ::
  for /f "tokens=* delims=" %%r in ('
    type stderr.tmp') do echo @set var_=%%r>tmp$$$.cmd
  if exist tmp$$$.cmd call tmp$$$.cmd
  ::
  if defined var_ (
    echo var_=%var_%
    ) else (
    echo var_ is undefined. The DIR command was successful.
    )
  ::
  for %%f in (stderr.tmp tmp$$$.cmd) do if exist %%f del %%f
  endlocal & goto :EOF

The output (slightly condensed) will be
  C:\_D\TEST>cmdfaq
   Directory of C:\_D\TEST
  var_=File Not Found

Or, if you instead have in the script
   dir MyExisting.txt 2>stderr.tmp
the output (again slightly condensed) will be
  C:\_D\TEST>cmdfaq
   Directory of C:\_D\TEST
  16.04.2006  06:36               523 MyExisting.txt
                 1 File(s)            523 bytes
                 0 Dir(s)  27 814 150 144 bytes free
  var_ is undefined. The DIR command was successful.

Consider the following example code which demonstrates several special
tricks of command line script programming
  @echo off & setlocal enableextensions
  copy "C:\_D\TEST\My file.txt" "C:\_M\TEMP\" >nul 2>&1^
    &&(echo The copying succeeded&goto _continue)^
      ||(echo The copying failed&echo Exiting&goto :EOF)
  :_continue
  echo Continuing whatever ...
  endlocal & goto :EOF

   1. Suppressing standard output
   2. Suppressing a potential error message
   3. Continuing a line
   4. Run a command if the preceding command is successful.
   5. Enclosing a set of commands in parentheses
   6. Run a command if the preceding command fails.
   7. Multiple commands on one line

The output could be e.g.
  C:\_D\TEST>cmdfaq
  The copying succeeded
  Continuing whatever ...
or
  C:\_D\TEST>cmdfaq
  The copying failed
  Exiting

References/Comments:
 hh ntcmds.chm::/redirection.htm
 hh ntcmds.chm::/ntcmds_shelloverview.htm
 http://www.google.com/groups?selm=1138300141.619659.182690%40z14g2000cwz.googlegroups.com
 http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:10 2011
Subject: 10) How can I change the environment variable values within a FOR loop?
Date: Mon, 31 Jan 2011 01:00:10
From: ts@uwasa.fi (Timo Salmi)

Unless enabledelayedexpansion is on, by default a for loop expands
its environment variables before the execution of the loop. Unlike
in programming with compilers the value of a variable that is
changed within a loop will not be set to its new value until the
loop is exited. (The same goes for any environment variable
expression on multiple lines within parentheses.)

For more information type SET /?
Also see item #158. (Similar issues go for the statements within IF
conditions.)

Consider the following example of a typical, but partly faulty attempt
to count the number of lines in a file
  @echo off & setlocal enableextensions
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (first second third fourth) do (
    echo This is the %%f line>>myfile.txt)
  ::
  set lineCount=0
  ::
  for /f "delims=" %%r in ('type myfile.txt') do (
    set /a lineCount+=1
    echo %lineCount% %%r
    )
  echo The number of lines is %lineCount%
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF
The output will obviously not be quite what one would want:
  D:\TEST>cmdfaq
  0 This is the first line
  0 This is the second line
  0 This is the third line
  0 This is the fourth line
  The number of lines is 4

There are ways to amend. One is to put the operations into a
subroutine outside the loop as follows
  @echo off & setlocal enableextensions
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (first second third fourth) do (
    echo This is the %%f line>>myfile.txt)
  ::
  set lineCount=0
  ::
  for /f "delims=" %%r in ('type myfile.txt') do (
    call :WriteOneLine %%r
    )
  echo The number of lines is %lineCount%
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  :: =============================================
  :WriteOneLine
  set /a lineCount+=1
  echo %lineCount% %*
  goto :EOF
The output will be
  D:\TEST>cmdfaq
  1 This is the first line
  2 This is the second line
  3 This is the third line
  4 This is the fourth line
  The number of lines is 4

The other option is to enable "delayed expansion"
  @echo off & setlocal enableextensions enabledelayedexpansion
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (first second third fourth) do (
    echo This is the %%f line>>myfile.txt)
  ::
  set lineCount=0
  ::
  for /f "delims=" %%r in ('type myfile.txt') do (
    set /a lineCount+=1
    echo !lineCount! %%r
    )
  echo The number of lines is %lineCount%
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF
The value of an environment variable in delayed expansion in the
above is to be indicated by !variable! instead of the more familiar
%variable%. The output will be
  D:\TEST>cmdfaq
  1 This is the first line
  2 This is the second line
  3 This is the third line
  4 This is the fourth line
  The number of lines is 4


There is an interesting and sometimes useful twist using call.
Consider (note, no delayed expansion needed)
  @echo off & setlocal enableextensions disabledelayedexpansion
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (first second third fourth) do (
    echo This is the %%f line>>myfile.txt)
  ::
  set lineCount=0
  ::
  for /f "delims=" %%r in ('type myfile.txt') do (
    set /a lineCount+=1
    call set line[%%lineCount%%]=%%r
    )
  echo The number of lines is %lineCount%
  for /L %%i in (1,1,%lineCount%) do call echo %%i %%line[%%i]%%
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  The number of lines is 4
  1 This is the first line
  2 This is the second line
  3 This is the third line
  4 This is the fourth line

Now, which one should one choose? Depends on the particulars. The
advantage with the disabledelayedexpansion methods is that they are
more tolerant of the poison characters &()[]{}^=;!'+,`~

Note, incidentally, that if there are empty lines in myfile.txt, those
empty lines are ignored by the FOR /F loop. Also note the disappearace
of the exclamation mark !. For example
  @echo off & setlocal enableextensions disabledelayedexpansion
  :: Make a test file
  for %%f in ("myfile.txt") do if exist %%f del %%f
  for %%f in (first "second &()[]{}^=;!'+,`~" third fourth) do (
    echo This is the %%f line>>"myfile.txt")
  echo.>>"myfile.txt"
  for %%f in (sixth seventh) do (
    echo This is the %%f line>>"myfile.txt")
  ::
  type "myfile.txt"
  pause
  ::
  setlocal enableextensions enabledelayedexpansion
  set lineCount=0
  ::
  for /f "delims=" %%r in ('type "myfile.txt"') do (
    set /a lineCount+=1
    echo !lineCount! %%r
    )
  echo The number of lines is %lineCount%
  ::
  :: Clean up
  for %%f in ("myfile.txt") do if exist %%f del %%f
  endlocal & goto :EOF
The output:
  C:\_D\TEST>cmdfaq
  This is the first line
  This is the "second &()[]{}^=;!'+,`~" line
  This is the third line
  This is the fourth line

  This is the sixth line
  This is the seventh line
  Press any key to continue . . .
  1 This is the first line
  2 This is the "second &()[]{}=;'+,`~" line
  3 This is the third line
  4 This is the fourth line
  5 This is the sixth line
  6 This is the seventh line
  The number of lines is 6

Consider the following task. I needed to output the sequence
            Item001.pdf
            Item002.pdf
            Item003.pdf
            Item004.pdf
            Item005.pdf
            Item006.pdf
            Item007.pdf
            :
            Item205.pdf
            Item206.pdf

The solution is e.g.
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /L %%i in (1,1,206) do (
    set iii=000%%i
    set iii=!iii:~-3!
    echo             Item!iii!.pdf)
  endlocal & goto :EOF

To conclude this FAQ item, an extra example of a for loop, using this
time the subroutine method
  @echo off
  ::
  :: A true life example of an XP script used in a repetitive task.
  :: It well demonstrates how change the values of environment
  :: variable WITHIN a FOR loop.
  ::
  echo.+-------------------------------------------------------------+
  echo ^| Convert Timo's IBM PC character text mail files into LATIN1 ^|
  echo ^| By Prof. Timo Salmi, Last modified Tue 25-November-2003     ^|
  echo +-------------------------------------------------------------+
  echo.
  ::
  :: Ask for confirmation before we go on, case insensitive
  set /p ask_=Convert, are you sure [y/N]?
  if /i not "%ask_%"=="y" if /i not "%ask_%"=="yes" goto :EOF
  :: It is prudent practice to release the query variable immediately
  :: (even if in this particular script it happens to be the only question)
  set ask_=
  ::
  :: Set the path for the origin and target files
  :: The names of the files is meant to stay the same
  set pathin_=C:\_D\MAIL
  set pathout_=C:\Documents and Settings\ts\mail
  ::
  :: Go trough all the relevant files
  :: and call the pseudo-subroutine for each one
  for %%f in (BATCH.MAI
  NEWS0001.MAI
  SCIWK001.MAI
  TIMO.MAI
  TIMO0001.MAI
  TIMO0002.MAI
  TIMO0003.MAI
  TIMO0004.MAI
  WORK0001.MAI
  WORK0002.MAI) do call :_subru %%f
  ::
  :: Finally clean up (instead of playing around with setlocal and endlocal)
  for %%v in (pathin_ pathout_ filein_ fileout_) do set %%v=
  :: Exit the script
  goto :EOF
  ::
  :: *** The pseudo-subroutine for each loop ***
  ::
  :_subru
  set filein_="%pathin_%\%1"
  set fileout_="%pathout_%\%1"
  ::
  :: Do the actual task
  :: note that this way we can easily have redirection within the loop
  :: IBM2LAT1 is an external (Turbo Pascal 7.01) filter program
  :: But that is beside the point since we could have any task here
  :: (Performs the same task as item #28)
  IBM2LAT1 < %filein_% > %fileout_%
  ::
  :: Show the relevant files at each loop, date/time size fullname
  for /f "tokens=1 delims=" %%f in (%filein_%)  do echo %%~tf %%~zf %%~ff
  for /f "tokens=1 delims=" %%f in (%fileout_%) do echo %%~tf %%~zf %%~ff
  echo.
  goto :EOF

References/Comments:
  hh ntcmds.chm::/for.htm
  hh ntcmds.chm::/set.htm
  http://www.google.com/groups?selm=48f3f3d7$0$10568$5a62ac22%40per-qv1-newsreader-01.iinet.net.au
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:11 2011
Subject: 11) How do I retain my original code page in these scripts?
Date: Mon, 31 Jan 2011 01:00:11
From: ts@uwasa.fi (Timo Salmi)

  @echo off
  for /f "tokens=3 delims= " %%p in (
    'mode con: codepage /status ^| find "Code page"') do (
    set store_codepage_=%%p)
  echo The stored codepage is %store_codepage_%
  ::
  mode con: codepage select=850
  echo Whatever ...
  ::
  mode con: codepage select=%store_codepage_%

More importantly, the regional settings which are used in this FAQ
collection require a DD.MM.YYYY HH:MN format. Hence, if your locale's
diverge, some of the scripts will need appropriate adjustments.

Likewise, some scripts may be affected by setting the time zone
environment variable TZ. When set in this FAQ, it will have the value
Europe/Helsinki or on occasions it must not be set at all to get the
datetime stamps right. For example, some touch utilities confuse the
datestamps if TZ is set. On the other hand the MS-DOS PGP program
requires that TZ is set.

References/Comments:
 hh ntcmds.chm::/mode.htm
 http://en.wikipedia.org/wiki/Code_page
 http://www.microsoft.com/globaldev/reference/oem.mspx
 http://www.microsoft.com/globaldev/reference/iso.mspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:12 2011
Subject: 12) How can I rename all my .JPG files sequentially in a folder?
Date: Mon, 31 Jan 2011 01:00:12
From: ts@uwasa.fi (Timo Salmi)

This is an instructive task, so let's go through it in several
intermediate steps. First consider
  @echo off & setlocal enableextensions
  set count_=1
  for /f "tokens=*" %%f in (
    'dir /s /b /-c /a:-d-s-h /o:n
    "C:\_G\WWW\~TS\GALLERY2\*.jpg"') do (
    call :_subru1 "%%~f")
  echo End of the first test
  endlocal & goto :EOF
  ::
  :_subru1
  echo %count_% "%~d1" "%~p1" "%~n1" "%~x1"
  set /a count_+=1
  goto :EOF
(As a sideline note how the FOR /F command can be continued onto
several lines.)

A screen capture would turn out something like below to demonstrate
some of the ~ modifiers on variables. The example also demonstrates
incrementing the value of an environment variable (count_) in a
loop-like manner. Furthermore observe the handling of the
possibility of long file names.
  C:\_D\TEST>cmdfaq
  1 "C:" "\_G\WWW\~TS\GALLERY2\" "ABSORB scaled" ".JPG"
  2 "C:" "\_G\WWW\~TS\GALLERY2\" "ABSORB" ".JPG"
  3 "C:" "\_G\WWW\~TS\GALLERY2\" "BIKEMIR" ".JPG"
  4 "C:" "\_G\WWW\~TS\GALLERY2\" "CATEYE scaled" ".JPG"
  5 "C:" "\_G\WWW\~TS\GALLERY2\" "CATEYE" ".JPG"
  6 "C:" "\_G\WWW\~TS\GALLERY2\" "CRESBAG scaled" ".JPG"
  7 "C:" "\_G\WWW\~TS\GALLERY2\" "CRESBAG" ".JPG"
  8 "C:" "\_G\WWW\~TS\GALLERY2\" "CRESCE2 scaled" ".JPG"
  9 "C:" "\_G\WWW\~TS\GALLERY2\" "CRESCE2" ".JPG"
  10 "C:" "\_G\WWW\~TS\GALLERY2\" "CRESCEN scaled" ".JPG"
  11 "C:" "\_G\WWW\~TS\GALLERY2\" "CRESCENT" ".JPG"
  :
  84 "C:" "\_G\WWW\~TS\GALLERY2\" "TimoSalmi 60v" ".jpg"
  85 "C:" "\_G\WWW\~TS\GALLERY2\" "TimoSalmi 70x100" ".jpg"
  86 "C:" "\_G\WWW\~TS\GALLERY2\" "WELLGO" ".JPG"
  87 "C:" "\_G\WWW\~TS\GALLERY2\PLAIN\" "BIKEMIR_" ".JPG"
  88 "C:" "\_G\WWW\~TS\GALLERY2\PLAIN\" "CRESCE2_" ".JPG"
  89 "C:" "\_G\WWW\~TS\GALLERY2\PLAIN\" "KULKUE_" ".JPG"
  End of the first test

LIMITATIONS: One of the things that we immediately observe is that
all potential subfolders are included. If you use paths in the way I
did in the above, then you must include the all subfolders switch /s
to get at the correct full path. Alternatively, you could drop the
/s but then you must run the script in the folder where your
relevant *.JPG files are. Else you will get incorrect paths. See
later below.

A word for warning. It would be advisable to avoid having "poison
characters" &()[]{}^=;!'+,`~ in one's file names when one
processes them with command line scripting.

Next step. Let's be prudent and not do the actual renaming but
instead create the scripts commands for the purpose:
  @echo off & setlocal enableextensions
  set count_=1
  for /f "tokens=*" %%f in (
    'dir /s /b /-c /a:-d-s-h /o:n
    "C:\_G\WWW\~TS\GALLERY2\*.jpg"') do (
    call :_subru1 "%%~f")
  echo End of the second test
  endlocal & goto :EOF
  ::
  :_subru1
  setlocal
    set dr_=%~d1& set pth_=%~p1& set base_=%~n1& set ext_=%~x1
    echo @ren "%dr_%%pth_%%base_%%ext_%" "%base_%.%count_%%ext_%"
  endlocal
  set /a count_+=1
  goto :EOF
(If you are wondering about the ampersand & it just is to
demonstrate putting several commands on one line.)

We would get
  C:\_D\TEST>cmdfaq
  @ren "C:\_G\WWW\~TS\GALLERY2\ABSORB scaled.JPG" "ABSORB scaled.1.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\ABSORB.JPG" "ABSORB.2.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\BIKEMIR.JPG" "BIKEMIR.3.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CATEYE scaled.JPG" "CATEYE scaled.4.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CATEYE.JPG" "CATEYE.5.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESBAG scaled.JPG" "CRESBAG scaled.6.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESBAG.JPG" "CRESBAG.7.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCE2 scaled.JPG" "CRESCE2 scaled.8.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCE2.JPG" "CRESCE2.9.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCEN scaled.JPG" "CRESCEN scaled.10.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCENT.JPG" "CRESCENT.11.JPG"
  :
  @ren "C:\_G\WWW\~TS\GALLERY2\TimoSalmi 60v.jpg" "TimoSalmi 60v.84.jpg"
  @ren "C:\_G\WWW\~TS\GALLERY2\TimoSalmi 70x100.jpg" "TimoSalmi 70x100.85.jpg"
  @ren "C:\_G\WWW\~TS\GALLERY2\WELLGO.JPG" "WELLGO.86.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\PLAIN\BIKEMIR_.JPG" "BIKEMIR_.87.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\PLAIN\CRESCE2_.JPG" "CRESCE2_.88.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\PLAIN\KULKUE_.JPG" "KULKUE_.89.JPG"
  End of the second test

OK, but that is not quite all what we want. Let's polish by adding
leading zeroes so that the added number always is four digits long.
  @echo off & setlocal enableextensions
  set count_=1
  for /f "tokens=*" %%f in (
    'dir /s /b /-c /a:-d-s-h /o:n
    "C:\_G\WWW\~TS\GALLERY2\*.jpg"') do (
    call :_subru1 "%%~f")
  echo rem End of the concluding test
  endlocal & goto :EOF
  ::
  :_subru1
  setlocal
    set dr_=%~d1
    set pth_=%~p1
    set base_=%~n1
    set ext_=%~x1
    set CountWithLead=0000%count_%
    set CountWithLead=%CountWithLead:~-4%
    echo @ren "%dr_%%pth_%%base_%%ext_%" "%base_%.%countWithLead%%ext_%"
  endlocal
  set /a count_+=1
  goto :EOF
The output
  C:\_D\TEST>cmdfaq
  @ren "C:\_G\WWW\~TS\GALLERY2\ABSORB scaled.JPG" "ABSORB scaled.0001.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\ABSORB.JPG" "ABSORB.0002.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\BIKEMIR.JPG" "BIKEMIR.0003.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CATEYE scaled.JPG" "CATEYE scaled.0004.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CATEYE.JPG" "CATEYE.0005.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESBAG scaled.JPG" "CRESBAG scaled.0006.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESBAG.JPG" "CRESBAG.0007.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCE2 scaled.JPG" "CRESCE2 scaled.0008.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCE2.JPG" "CRESCE2.0009.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCEN scaled.JPG" "CRESCEN scaled.0010.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCENT.JPG" "CRESCENT.0011.JPG"
  :
  @ren "C:\_G\WWW\~TS\GALLERY2\TimoSalmi 60v.jpg" "TimoSalmi 60v.0084.jpg"
  @ren "C:\_G\WWW\~TS\GALLERY2\TimoSalmi 70x100.jpg" "TimoSalmi 70x100.0085.jpg"
  @ren "C:\_G\WWW\~TS\GALLERY2\WELLGO.JPG" "WELLGO.0086.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\PLAIN\BIKEMIR_.JPG" "BIKEMIR_.0087.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\PLAIN\CRESCE2_.JPG" "CRESCE2_.0088.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\PLAIN\KULKUE_.JPG" "KULKUE_.0089.JPG"
  rem End of the concluding test

One further step. Rewrite the above more concisely. The added
advantage is that this version is more tolerant of the poison
characters.
  @echo off & setlocal enableextensions
  set count_=1
  for /f "tokens=*" %%f in (
    'dir /s /b /-c /a:-d-s-h /o:n
    "C:\_G\WWW\~TS\GALLERY2\*.jpg"') do (
    call :_subru1 "%%~f")
  echo rem End of the concluding test
  endlocal & goto :EOF
  ::
  :_subru1
  setlocal
    set CountWithLead=0000%count_%
    set CountWithLead=%CountWithLead:~-4%
    echo @ren "%~d1%~p1%~n1%~x1" "%~n1.%countWithLead%%~x1"
  endlocal
  set /a count_+=1
  goto :EOF
Now there you have it. Just redirect the output to a command file,
and you are all set to do the renaming, maybe after some editing of
your own of the resultant command line file.
  C:\_D\TEST>cmdfaq > DOIT.CMD
  C:\_D\TEST>DOIT

Now let's do the same task, but this time omit any subfolders.
  @echo off & setlocal enableextensions
  set dir_=C:\_G\WWW\~TS\GALLERY2
  if not exist "%dir_%\" (
    echo Folder "%dir_%\" not found
    goto :EOF)
  pushd "%dir_%"
  set count_=1
  for /f "tokens=*" %%f in (
    'dir /b /a:-d-s-h /o:n "*.jpg"') do (
    call :_subru1 "%%~f")
  popd
  endlocal & goto :EOF
  ::
  ::
  :_subru1
  setlocal
  set CountWithLead=0000%count_%
  set CountWithLead=%CountWithLead:~-4%
  echo @ren "%~d1%~p1%~n1%~x1" "%~n1.%countWithLead%%~x1"
  endlocal
  set /a count_+=1
  goto :EOF
The output
  C:\_D\TEST>cmdfaq
  @ren "C:\_G\WWW\~TS\GALLERY2\ABSORB scaled.JPG" "ABSORB scaled.0001.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\ABSORB.JPG" "ABSORB.0002.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\BIKEMIR.JPG" "BIKEMIR.0003.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CATEYE scaled.JPG" "CATEYE scaled.0004.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CATEYE.JPG" "CATEYE.0005.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESBAG scaled.JPG" "CRESBAG scaled.0006.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESBAG.JPG" "CRESBAG.0007.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCE2 scaled.JPG" "CRESCE2 scaled.0008.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCE2.JPG" "CRESCE2.0009.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCEN scaled.JPG" "CRESCEN scaled.0010.JPG"
  @ren "C:\_G\WWW\~TS\GALLERY2\CRESCENT.JPG" "CRESCENT.0011.JPG"
  :
  @ren "C:\_G\WWW\~TS\GALLERY2\TimoSalmi 60v.jpg" "TimoSalmi 60v.0084.jpg"
  @ren "C:\_G\WWW\~TS\GALLERY2\TimoSalmi 70x100.jpg" "TimoSalmi 70x100.0085.jpg"
  @ren "C:\_G\WWW\~TS\GALLERY2\WELLGO.JPG" "WELLGO.0086.JPG"

The problem can also be solved with a Visual Basic Script (VBScript)
aided command line script
  @echo off & setlocal enableextensions
  ::
  :: Set the source folder and check that it contains .JPG files
  set SourceDir=C:\_M
  if not exist "%SourceDir%\*.JPG" (
    echo No .JPG files found in "%SourceDir%"
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set vbs_=%temp_%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%SourceDir%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  '
  Set arg = WScript.Arguments 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set f = fso.GetFolder(arg(0)) 'VBS
  Set fc = f.Files 'VBS
  Set i=0
  For Each f1 in fc 'VBS
    extension = fso.GetExtensionName(f1) 'VBS
    If UCase(extension) = "JPG" Then 'VBS
      i = i + 1 'VBS
      s = "rem @ren " & Chr(34) 'VBS
      s = s & f1 & Chr(34) & " " & Chr(34) 'VBS
      basename = fso.GetBaseName(f1) 'VBS
      s = s & basename 'VBS
      s = s & PadFn(CStr(i),4) 'VBS
      s = s & "." & extension & Chr(34) 'VBS
      Wscript.Echo s 'VBS
    End If 'VBS
  Next 'VBS
  '
  Function PadFn (str, n) 'VBS
    PadFn = Right(String(n-1,"0")&str,n) 'VBS
  End Function 'VBS

The (double safety) output might be e.g. the following. It can be
redirected to a new batch file which in turn can be run after one is
convinced that it is exactly what one wants.
  C:\_D\TEST>cmdfaq
  rem @ren "C:\_M\ABSORB.JPG" "ABSORB0001.JPG"
  rem @ren "C:\_M\bikemir.jpg" "bikemir0002.jpg"
  rem @ren "C:\_M\CATEYE.JPG" "CATEYE0003.JPG"
  rem @ren "C:\_M\CRESBAG.JPG" "CRESBAG0004.JPG"
  rem @ren "C:\_M\PEUGBAG.JPG" "PEUGBAG0005.JPG"
  rem @ren "C:\_M\PEUGEOT.JPG" "PEUGEOT0006.JPG"
  rem @ren "C:\_M\PRPUMP.JPG" "PRPUMP0007.JPG"
  rem @ren "C:\_M\SKATES.JPG" "SKATES0008.JPG"
  rem @ren "C:\_M\SKIEQUIP.JPG" "SKIEQUIP0009.JPG"
  rem @ren "C:\_M\SONYRAD.JPG" "SONYRAD0010.JPG"
  rem @ren "C:\_M\TACX.JPG" "TACX0011.JPG"
  rem @ren "C:\_M\WELLGO.JPG" "WELLGO0012.JPG"

The original question and the consequent thread in alt.msdos.batch.nt
which prompted me to add the VBS-aided solution was
  "I am attempting to rename a large amount of files using a sequence,
  i.e.,...I want the files renamed to FILE1.DOC, FILE2.DOC, etc.... any
  way I can rename  about 400 files automatically in a sequence as
  described."

To do exactly that, the required changes in the code above are
minimal. Change JPG to DOC (the two instances) and change
    basename = fso.GetBaseName(f1) 'VBS
to
    basename = "FILE" 'VBS

We might then have an output something like
  C:\_D\TEST>cmdfaq
  rem @ren "C:\_M\OFFISUNS.DOC" "FILE0001.DOC"
  rem @ren "C:\_M\OFFIVIEW.DOC" "FILE0002.DOC"

Below is a true-life pure script I occasionally apply myself:
  @echo off & setlocal enableextensions
  echo @rem +----------------------------------------------------+
  echo @rem : JPGRENAM.CMD Special rename a set of *.jpg files   :
  echo @rem : By Prof. Timo Salmi, Last modified Fri 26-Sep-2008 :
  echo @rem +----------------------------------------------------+
  echo @rem
  ::
  :: Avoid multiple calls of the script
  if exist "%temp%\jpgrenamLockfile.tmp" (
    echo An instance of JPGRENAM.CMD already is running
    echo If this is in error delete the lockfile
    echo "%temp%\jpgrenamLockfile.tmp"
    if not defined cmdbox if defined PauseIfFromDesktop pause
    goto :EOF
    )
  echo Lockfile "%temp%\jpgrenamLockfile.tmp" for JPGRENAM.CMD>"%temp%\jpgrenamLockfile.tmp"
  ::
  :: Parameters, customize the first for your own folder
  set sourceFolder=C:\_M
  set Basename=%~1
  set Number=1
  if not "%~2"=="" set Number=%~2
  ::
  :: Is help needed
  if "%~1"=="" goto _help
  if "%~1"=="?" goto _help
  if "%~1"=="/?" goto _help
  if /i "%~1"=="/help" goto _help
  ::
  :: Any files there?
  if not exist "%sourceFolder%\*.JPG" (
    echo No JPG files found in "%sourceFolder%"
    goto _out
  )
  ::
  :: Process
  pushd "%sourceFolder%"
  for /f "tokens=*" %%f in ('
    dir /b /a-d-s "%sourceFolder%\*.jpg"') do (
      call :ProcessOneFile "%%~ff")
  popd
  echo @dir /b /a-d-s "%sourceFolder%\%Basename%*.jpg"
  goto _out
  ::
  :_help
  echo.
  echo Usage: JPGRENAM [NewBasename] [NewStartNumber]
  echo.
  echo E.g. JPGRENAM Photo 20
  echo JPGRENAM Pict ^> Doit.cmd
  goto _out
  ::
  :_out
  for %%f in ("%temp%\jpgrenamLockfile.tmp") do if exist %%f del %%f
  if not defined cmdbox if defined PauseIfFromDesktop pause
  endlocal & goto :EOF
  ::
  :: ================================================================
  :ProcessOneFile
  setlocal
    set NumberWithLead=000%Number%
    set NumberWithLead=%NumberWithLead:~-3%
    echo @ren "%~n1%~x1" "%Basename%%NumberWithLead%%~x1"
  endlocal
  set /a Number+=1
  goto :EOF

An example screen capture:
  C:\_M>dir *.jpg
   Volume in drive C is
   Volume Serial Number is
   Directory of C:\_M
  25.09.2008  17:55           239,377 Passtime.jpg
  25.09.2008  17:55           449,651 Skyline2.jpg
  25.09.2008  17:55           271,416 University.jpg
                 3 File(s)        960,444 bytes
                 0 Dir(s)  230,515,130,368 bytes free

  C:\_M>jpgrenam Pict
  @rem +----------------------------------------------------+
  @rem : JPGRENAM.CMD Rename the *.jpg files of others      :
  @rem : By Prof. Timo Salmi, Last modified Fri 26-Sep-2008 :
  @rem +----------------------------------------------------+
  @rem
  @ren "Passtime.jpg" "Pict001.jpg"
  @ren "Skyline2.jpg" "Pict002.jpg"
  @ren "University.jpg" "Pict003.jpg"
  @dir /b /a-d-s "C:\_M\Pict*.jpg"

You might wish to see also Item #178.

References/Comments:
 http://www.google.com/groups?selm=6SWIb.34109%24_P.1466245%40news4.tin.it
 http://technet2.microsoft.com/windowsserver/en/library/97731e49-ffa3-4918-87fb-5318743f29321033.mspx?mfr=true
 http://www.google.com/groups?selm=342f1184-3b8e-4888-b6b1-d7bf8b92f4b6%40r35g2000prm.googlegroups.com
 http://www.google.com/groups?selm=8_2sk.22500$N87.9369%40nlpi068.nbdc.sbc.com

Dr. John Stockton: "To get always 4 digits, one way is to count from
10001 and take the last 4 of the 5 characters. Or just to number
from 10001 or 10000."
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:13 2011
Subject: 13) How do I get the current day of the week?
Date: Mon, 31 Jan 2011 01:00:13
From: ts@uwasa.fi (Timo Salmi)

For today we have utilizing G(nu)Awk
  @echo off & setlocal enableextensions
  rem Requires gawk
  gawk 'BEGIN{printf"@set wd_=%%s\n",strftime("%%a")}'>"%TEMP%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%TEMP%\tmp$$$.cmd"
  echo The weekday today is %wd_%
  set wd_=
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  The weekday today is Thu

Or
  @echo off & setlocal enableextensions
  rem Requires gawk (See item #6)
  unxgawk "BEGIN{printf\"@set wd_=%%s\n\",strftime(\"%%a\")}">"%TEMP%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%TEMP%\tmp$$$.cmd"
  echo The weekday today is %wd_%
  set wd_=
  endlocal & goto :EOF
Or, if one has a UNIX-port date (let's call it unxdate for
distinction) we can have
  @echo off & setlocal enableextensions
  for /f %%a in ('unxdate "+%%a"') do set wd_=%%a
  echo wd_=%wd_%
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  wd_=Thu

For yesterday
  @echo off & setlocal enableextensions
  rem Requires gawk
  gawk 'BEGIN{printf"@set wd_=%%s\n",strftime("%%a",systime()-24*60*60)}'>"%TEMP%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%TEMP%\tmp$$$.cmd"
  echo The weekday yesterday was %wd_%
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  The weekday yesterday was Wed

Another option for today's weekday is
  @echo off
  ::
  :: Get and show today's Julian date number
  :: Requires DATE2NUM.EXE from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
  DATE2NUM /set>"%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  echo datenum_=%datenum_%
  ::
  :: Convert the result into a weekday number (Mon=1 to Sun=7)
  set /a wd_=(%datenum_% %% 7) + 1
  echo wd_=%wd_%
  ::
  :: Convert the weekday into three letters
  for /f "tokens=%wd_%" %%d in ('echo Mon Tue Wed Thu Fri Sat Sun') do echo %%d
  ::
  :: Clean up
  for %%v in (datenum_ wd_) do set %%v=
The output on Thu 30-Jun-2005 would have been
  C:\_D\TEST>cmdfaq
  datenum_=2453552
  wd_=4
  Thu

Incidentally, for SET/A the line
  set /a wd_=(%datenum_% %% 7) + 1
could be also written as
  set /a wd_=(datenum_ %% 7) + 1

Apropos %mytemp%. If not (pre)set, the temporary files will go to
the root directory.

The problem can also be solved with a Visual Basic Script (VBScript)
aided command line script
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp%\tmp$$$.vbs"
  :: Call the command line script the script host built
  call "%temp%\tmp$$$.cmd"
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  :: Show the result
  echo wd_=%wd_%
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Const ForReading = 1, ForWriting = 2, ForAppending = 8             'VBS
  Dim DateNow, fso, f, MyTemp, TempFile                              'VBS
  DateNow = Date                                                     'VBS
  Set WshShell = WScript.CreateObject("WScript.shell")               'VBS
  MyTemp=WshShell.ExpandEnvironmentStrings("%temp%")                 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject")               'VBS
  TempFile = MyTemp & "\tmp$$$.cmd"                                  'VBS
  Set f = fso.OpenTextFile(TempFile, ForWriting, True)               'VBS
  f.Write "@set wd_=" & WeekDayName(Weekday(DateNow),true)           'VBS
  f.Close                                                            'VBS

Or, much more concisely
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo WeekDayName(Weekday(Date),true)
  for /f %%d in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set wd_=%%d
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo Weekday wd_=%wd_%
  endlocal & goto :EOF
The output could be e.g.
  D:\TEST>cmdfaq
  Weekday wd_=Thu

Using a number to indicate the weekday instead of the letters
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo Weekday(Date,vbMonday)
  for /f %%d in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set wd_=%%d
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo Weekday number ^(with Monday as 1^) wd_=%wd_%
  endlocal & goto :EOF
The output could be e.g.
  D:\TEST>cmdfaq
  Weekday number (with Monday as 1) wd_=4
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:14 2011
Subject: 14) Help! My old batch files won't work since there is no choice.
Date: Mon, 31 Jan 2011 01:00:14
From: ts@uwasa.fi (Timo Salmi)

 Q: When I try to run my old batch file as a CMD.EXE script I get
"'choice' is not recognized as an internal or external command,
operable program or batch file." What can I do?

 A: The CHOICE command has been dropped because allegedly it can
cause collisions in the NT/2000/XP multi-tasking environment. Thus
the best choice (if you pardon the pun) is not try to find an old
version, but patiently write your scripts anew using SET /P. However,
choice is back on Vista. Anyway, below is a simple demonstration
of the set /p usage.

  @echo off & setlocal enableextensions
  :_again
  set ask_=
  set /p ask_="Please respond [y,n,q]?"
  for %%a in (y n q) do if /i "%ask_%"=="%%a" goto _%%a
  goto _again
  ::
  :_y
  echo Your input was Yes& goto :EOF
  :_n
  echo Your input was No& goto :EOF
  :_q
  echo Your input was Quit& goto :EOF
  endlocal & goto :EOF

The same with a slightly different logic, and a default.
  @echo off & setlocal enableextensions
  :_again
  set ask_=
  set /p ask_="Please respond [Y,n,q]?"
  if /i "%ask_%"=="q" goto _q
  if /i "%ask_%"=="n" goto _n
  if /i not "%ask_%"=="y" if not "%ask_%"=="" goto _again
  goto _y
  ::
  :_y
  echo Your input was Yes& goto :EOF
  :_n
  echo Your input was No& goto :EOF
  :_q
  echo Your input was Quit& goto :EOF
  endlocal & goto :EOF
The output could be e.g.
  D:\TEST>cmdfaq
  Please respond [Y,n,q]?n
  Your input was No

The line
  set /p ask_="Please respond [Y,n,q]?"
could alternatively be written as
  (set /p ask_=Please respond [Y,n,q]?)

The response could also be written as a subroutine. (The usefulness of
the option would become more obvious if the script contained several
questions.)
  @echo off & setlocal enableextensions
  Call :AskQuestionWithYdefault "Please respond [Y,n,q]?" reply_
  goto _%reply_%1
  ::
  :_y1
  echo Your input was Yes& goto :EOF
  :_n1
  echo Your input was No& goto :EOF
  :_q1
  echo Your input was Quit& goto :EOF
  endlocal & goto :EOF
  ::
  :: The question as a subroutine
  :AskQuestionWithYdefault
    setlocal enableextensions
    :_askthequestionagain
    set return_=
    set ask_=
    set /p ask_="%~1"
    if "%ask_%"=="" set return_=y
    if /i "%ask_%"=="Y" set return_=y
    if /i "%ask_%"=="n" set return_=n
    if /i "%ask_%"=="q" set return_=q
    if not defined return_ goto _askthequestionagain
  endlocal & set "%2=%return_%" & goto :EOF

Consider a snippet from a real-life script for "whatever" actual task.
If Opera (a browser, as you know) happens to be running, one wants to
ensure the user's permission to do the "whatever". Else one just
performs the "whatever" outright. Also note the if construct, which
requires using delayed expansion. As for the <CTRL-G>, it is the beep,
i.e. ASCII 7.
  echo off & setlocal enableextensions enabledelayedexpansion
  tasklist|find /i "opera.exe">nul
  if !errorlevel! EQU 0 (
    echo Opera is running<CTRL-G>
    call :ContinueOrNot reply_
    if "!reply_!"=="n" (endlocal & goto :EOF))
  echo Do here whatever you intend to do
  endlocal & goto :EOF
  ::
  :: The question as a subroutine
  :ContinueOrNot
  setlocal enableextensions
  :_askthequestionagain
  set ask_=
  set /p ask_="Continue nevertheless [y,N]?"
  if /i "%ask_%"=="y" (endlocal & set "%1=y" & goto :EOF)
  if not "%ask_%"=="" if /i not "%ask_%"=="n" goto _askthequestionagain
  endlocal & set "%1=n" & goto :EOF

Anyway, instead of the SET /P you might try a clone such as CHOOSE.
EXE "Ask questions in batch/script files" from
ftp://garbo.uwasa.fi/pc/ts/tsutlf17.zip or later.
(Now also included in tscmd.zip)
  @echo off & setlocal enableextensions
  choose /tq,5 /cynq "Give your answer "
  if errorlevel==0 if not errorlevel==1 echo You effected a break
  if errorlevel==1 if not errorlevel==2 echo Your input was Yes
  if errorlevel==2 if not errorlevel==3 echo Your input was No
  if errorlevel==3 if not errorlevel==4 echo Your input was Quit
  if errorlevel==255 echo Error condition
  endlocal & goto :EOF

Alternatively
  @echo off & setlocal enableextensions
  choose /tq,5 /cynq /x "Give your answer "
  for %%c in (call del) do %%c choose_.bat
  if "%choose_%"=="0" echo You effected a break
  if "%choose_%"=="1" echo Your input was Yes
  if "%choose_%"=="2" echo Your input was No
  if "%choose_%"=="3" echo Your input was Quit
  if "%choose_%"=="255" echo Error condition
  endlocal & goto :EOF

The output in both the cases might be e.g.
  D:\TEST>cmdfaq
  Give your answer [Y,N,Q]?Q
  Your input was Quit

The obvious advantage of CHOOSE.EXE over the SET /P method is that
the former can handle timed default input.

If you want Microsoft's old CHOICE.EXE it seems to be available from
the Microsoft Windows 98 Resource Kit e.g. at
ftp://ftp.microsoft.com/Services/TechNet/samples/PS/Win98/Reskit/SCRPTING
(For the tools included with the Microsoft Windows 98 Resource Kit
see http://support.microsoft.com/kb/247024)

References/Comments:
 hh ntcmds.chm::/set.htm
 http://www.google.com/groups?selm=3E1C6329.5020008%40uclink.berkeley.edu
 http://webtools.live2support.com/windows/choice.php
 http://webtools.live2support.com/windows/set.php
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:15 2011
Subject: 15) Is it possible to echo without linefeed like the Unix echo -n?
Date: Mon, 31 Jan 2011 01:00:15
From: ts@uwasa.fi (Timo Salmi)

At least with gawk, yes. The following example script demonstrates
  @echo off
  echo Testline 1|gawk '{printf"%%s",$0}'
  echo Testline 2|gawk '{printf"%%s",$0}'
  echo Testline 3|gawk '{printf"%%s\n",$0}'
The output will be
  C:\_D\TEST>cmdfaq
  Testline 1Testline 2Testline 3

Related subject: Re: Combining two single-line files into one single-
line file
Q: The following question was posed on the Usenet news:
  File1.txt contains: Asset #353
  File2.txt contains: 3-25-02
  I want File3.txt to contain: Asset #353 3-25-02
A: One, but not the only option is
  @echo off
  <File1.txt gawk '{printf"%%s",$0}'>File3.txt
  <File2.txt gawk '{printf" %%s\n",$0}'>>File3.txt

The sister package for MS-DOS+Win..95/98/ME
 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
 Useful MS-DOS batch files and tricks, T.Salmi
contains ECHON.EXE "echo -n, Echo without a linefeed"
which works also on NT/2000/XP (or at least XP, since I can't test
the others).

  @echo off & setlocal enableextensions
  C:\_F\BAT\ECHON Testline 1
  C:\_F\BAT\ECHON Testline 2
  C:\_F\BAT\ECHON Testline 3
  endlocal & goto :EOF

The output:
  D:\TEST>cmdfaq
  Testline 1Testline 2Testline 3

Many of the tsbat.zip solutions not necessarily included in
tscmd.zip work for NT/2000/XP. However, the reverse is not true.
Most of the code in tscmd.zip is not valid for MS-DOS+Win..95/98/Me.

The solutions in the comment demonstrate that this task can be
solved without external tools. The solution below is based on Phil's
posting. Note the ^ quoting of 1, 2, and 3 lest they be taken as
handles.

  @echo off & setlocal
  echo.|set /p=Testline ^1>tmp.txt
  echo.|set /p=Testline ^2>>tmp.txt
  echo.Testline ^3>>tmp.txt
  for %%c in (type del) do %%c tmp.txt
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  Testline 1 Testline 2 Testline 3

Alternatively
  @echo off & setlocal enableextensions
  <nul (set /p z="Testline 1 ")>tmp.txt
  <nul (set /p z="Testline 2 ")>>tmp.txt
  <nul (set /p z="Testline 3")>>tmp.txt
  echo.>>tmp.txt
  for %%c in (type del) do %%c tmp.txt
  endlocal & goto :EOF

The most concise method not producing a <CR><LF> pair is
  @echo off & setlocal enableextensions disabledelayedexpansion
  if not "%~1"=="" goto _nolfcr
  echo Usage: %~0 "Your text"
  goto :EOF
  ::
  :_nolfcr
  set /p="%~1"<nul
  endlocal & goto :EOF

As an aside, if for some unfathomable reason you want to create a
file of 1 byte (one, not two) then
  @echo off & setlocal enableextensions
  echo.|set /p=>myfile
  dir myfile
  endlocal & goto :EOF

The original problem can also be solved with a Visual Basic Script
(VBScript) aided command line script
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  > "%vbs_%" echo WScript.StdOut.Write "Prof. "
  >>"%vbs_%" echo WScript.StdOut.Write "Timo Salmi, "
  >>"%vbs_%" echo WScript.StdOut.Write "University of Vaasa, "
  >>"%vbs_%" echo WScript.StdOut.WriteLine "Finland"
  cscript //nologo "%vbs_%"
  echo See, it works!
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  Prof. Timo Salmi, University of Vaasa, Finland
  See, it works!

Alternatively, the VBS-aided command line script could be formulated as
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  (
    echo WScript.StdOut.Write "Prof. "
    echo WScript.StdOut.Write "Timo Salmi, "
    echo WScript.StdOut.Write "University of Vaasa, "
    echo WScript.StdOut.WriteLine "Finland"
  )>"%vbs_%"
  cscript //nologo "%vbs_%"
  echo See, it works!
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

Using VBS and the subroutine approach (slower) we can write
  @echo off & setlocal enableextensions
  call :EchoVbsN "Prof. "
  call :EchoVbsN "Timo Salmi, "
  call :EchoVbsN "University of Vaasa, "
  echo Finland
  echo See, it works!
  endlocal & goto :EOF
  ::
  :: =====================================
  :: Subroutine: Echo without the linefeed
  : EchoVbsN
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" echo WScript.StdOut.Write "%~1"
  cscript //nologo "%vbs_%"
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=%23qRDtfqtBHA.2608%40tkmsftngp04
 http://www.google.com/groups?selm=bsm4uq%24e6f4a%241%40ID-55492.news.uni-berlin.de
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:16 2011
Subject: 16) How can I get the time without having to press enter?
Date: Mon, 31 Jan 2011 01:00:16
From: ts@uwasa.fi (Timo Salmi)

You might first wish to revisit item #1.

Independently of the OS version
  @echo off
  echo.| time | find /v "new"
For example you might get
  The current time is:  8:46:29.15

However, in XP scripting the date and time variables are directly
available
  @echo off
  echo %time%
In this option you might get for example
  D:\TEST>cmdfaq
   9:03:13.56

Also
  @echo off
  time /t
which would produce (only) e.g.
  D:\TEST>cmdfaq
  09:03

There is a complication, however. Say that you wish to capture the
hour, alone. One has to take into account that the hour might have
one or two digits. One can't safely use %time:~0,2% so instead use
the for /f method:
  @echo off & setlocal enableextensions
  for /f "tokens=1 delims=:. " %%h in ("%time%") do set hh_=%%h
  echo %hh_%
  endlocal & goto :EOF
The output would be e.g.
  D:\TEST>cmdfaq
  9

If you want the potential leading zero, use TIME /T as follows (or
pad it as explained in item #127)
  @echo off & setlocal enableextensions
  for /f "tokens=1 delims=:. " %%h in ('time /t') do set hh_=%%h
  echo %hh_%
  endlocal & goto :EOF
The output would be e.g.
  D:\TEST>cmdfaq
  09

Octals are (confusingly) identified by a leading zero. Therefore
consider carefully when wish to have the leading zero. For example,
if you add to the above
  set /a hhplus1_=%hh_%+1
you'll get
  C:\_D\TEST>cmdfaq
  09
  Invalid number.  Numeric constants are either decimal (17),
  hexadecimal (0x11), or octal (021).

Another option
  @echo off & setlocal enableextensions
  ::
  :: Put the time in an auxiliary variable to fix the moment
  set time_=%time%
  ::
  :: Take care of the potential leading space for small hours
  set time_=%time_: =0%
  ::
  :: Extract the time elements
  set hh_=%time_:~0,2%
  set mn_=%time_:~3,2%
  set ss_=%time_:~6,2%
  set s100_=%time_:~9,2%
  ::
  :: Display
  echo %hh_% %mn_% %ss_% %s100_%
  endlocal & goto :EOF
The output might be e.g.
  D:\TEST>cmdfaq
  09 58 51 06

There are other alternatives, including a Visual Basic Script aided
command line script like the one already presented in item #1 about
the date variables.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:17 2011
Subject: 17) How can I avoid the potential "ECHO is off." in echoing %myvar%
Date: Mon, 31 Jan 2011 01:00:17
From: ts@uwasa.fi (Timo Salmi)

Use a period right after the echo.
  @echo off
  setlocal
  set myvar=This is a test
  echo.%myvar%
  set myvar=
  echo.%myvar%
  echo That's all
  endlocal

Which gives
  D:\TEST>cmdfaq
  This is a test

  That's all
Without the period (.) you'd get
  D:\TEST>cmdfaq
  This is a test
  ECHO is off.
  That's all

Of course, this always is valid
  @echo off & setlocal enableextensions
  set myvar=
  echo myvar=%myvar%
  set myvar=Hi there
  echo myvar=%myvar%
  endlocal & goto :EOF
The output:
  C:\_D\TEST>cmdfaq
  myvar=
  myvar=Hi there
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:18 2011
Subject: 18) How does one build re-usable script function modules?
Date: Mon, 31 Jan 2011 01:00:18
From: ts@uwasa.fi (Timo Salmi)

The best way to get started is making the simplest possible example.
Let's build and test one script function for addition and one for
subtraction. The arguments are passed by reference.

  @echo off
  setlocal enableextensions
  call :FuncAdd 3 5 sum_
  echo The sum is %sum_%
  call :FuncSub 3 5 diff_
  echo The difference is %diff_%
  goto :EOF

  :FuncAdd arg1_ arg2_ return_
  setlocal enableextensions
    set /a return_=%1+%2
  endlocal & set "%3=%return_%" & goto :EOF

  :FuncSub arg1_ arg2_ return_
  setlocal enableextensions
    set /a return_=%1-%2
  endlocal & set "%3=%return_%" & goto :EOF

The output:
  D:\TEST>cmdfaq
  The sum is 8
  The difference is -2

The arguments on the line :FuncAdd arg1_ arg2_ return_ are, in fact,
superfluous. They are permissible, though, and make for a better
documentation.

There are a number of re-usable subroutines in this FAQ, including for
example
  AskQuestionWithYdefault  BinToDecimal  checkVBS  DecimalToBinary
  DecimalToHex  DecimalToOctal  EchoVbsN  FuncRightJustify  GetStrLength
  GetVolSerialNr  HexToDecimal  InstrLastFN  IsAtPath  IsWildSub
  JDdayNumber  JDweekNumber  LeadVar  OctToDecimal  ProcDelay
  RemoveLeadingZeros  ShowFileinfo  TestForZeroFile  ToUpcase  TrimZeros

  VBS:  FileAgeFn  PadFn  PadLeftFn  ShowVolumeInfo  Slice
  TraverseOneFolder  TraverseManyFolders  WeekNumJRS

Furthermore, see e.g.
  GetOneRandomChar in MAKEPASS.CMD and ToLowCase in NAMEDOWN.CMD

References/Comments:
 http://groups.google.fi/group/alt.msdos.batch.nt/browse_thread/thread/50825a61ddd426a9
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:19 2011
Subject: 19) How can one build a delay / sleep / wait procedure for a script?
Date: Mon, 31 Jan 2011 01:00:19
From: ts@uwasa.fi (Timo Salmi)

The most often presented delay trick is using ping. For a two second
delay one can ping oneself as follows
  @echo off
  echo %time%
  ping -n 3 127.0.0.1>nul
  echo %time%
which would produce e.g.
  D:\TEST>cmdfaq
  15:24:47.57
  15:24:49.62
As you see, it is not dead accurate. But neither is the solution below
solution. Not that it usually is essential.

Another method is to observe the difference between the time the delay
is started and the current time. The calculations are in hundreds of a
second since midnight. (The rare potential case of straddling the
midnight is not covered.) The example below sleeps for about two and
a half seconds.
  @echo off & setlocal enableextensions
  echo %time%
  call :ProcDelay 250
  echo %time%
  endlocal & goto :EOF
  ::
  :ProcDelay delayMSec_
  setlocal enableextensions
    set time_=%time%
    set time_=%time_::0=:%
    set time_=%time_:.0=.%
    set time_=%time_: =%
    for /f "tokens=1-4 delims=:. " %%h in ('echo %time_%') do (
      set /a start_=360000*%%h+6000*%%i+100*%%j+%%k)
    :_procwaitloop
      set time_=%time%
      set time_=%time_::0=:%
      set time_=%time_:.0=.%
      set time_=%time_: =%
      for /f "tokens=1-4 delims=:. " %%h in ('echo %time_%') do (
        set /a now_=360000*%%h+6000*%%i+100*%%j+%%k)
      set /a diff_=%now_%-%start_%+3
    if %diff_% LSS %1 goto _procwaitloop
  endlocal & goto :EOF

The output e.g:
  D:\TEST>cmdfaq
  19:49:06.94
  19:49:09.45

Why the set time_=%time_::0=:% lines?

Furthermore, you could have a Visual Basic Script (VBScript) aided
command line script
  @echo off & setlocal enableextensions
  echo WScript.Sleep 1000 > "%temp%\tmp$$$.vbs"
  echo %time%
  cscript //nologo "%temp%\tmp$$$.vbs"
  echo %time%
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & goto :EOF
which would produce e.g.
  D:\TEST>cmdfaq
  13:13:03.00
  13:13:04.07
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:20 2011
Subject: 20) Is is possible to right-justify numbers or words in a script?
Date: Mon, 31 Jan 2011 01:00:20
From: ts@uwasa.fi (Timo Salmi)

Yes. Basically this is the same question as padding a variable with
leading blanks. E.g. you might have within a script
  set fsize_=         %%~zf
  set fsize_=!fsize_:~-10!

The more generic version of padding is given by the subroutine LeadVar
in item #127.
  LeadVar MyString PadWith MaxLength return_

Other cases of the padding in this FAQ include the later subroutines
in the item #12 "How can I rename all my .JPG files sequentially in a
folder?" and the FuncRightJustify routine in WHEREIS.CMD script
included in this collection. Furthermore, RightJustify10 in item #8.

For left-justification see item #96.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:21 2011
Subject: 21) Do you have pointers to additional script material and tips?
Date: Mon, 31 Jan 2011 01:00:21
From: ts@uwasa.fi (Timo Salmi)

Yes, some. But since the links to outside material may (or may not)
be transient and volatile in nature I will rather point to a web
page of mine carrying references to programming material. Link
directly to either
  http://lipas.uwasa.fi/~ts/http/http2.html#programming
  http://lipas.uwasa.fi/~ts/http/http2.html#cmdscript

Where do I find a detailed command-line reference?
  Left-click "start" in the Taskbar
   Enter "Command-line reference" into the Search window
    Two suggested topics should appear
     Choose from "Overviews, Articles and Tutorials"
      Click "Add to Favorites" to quickly locate the item in the future

Here are some other useful NT/2000/XP CMD.EXE command line scripts
programming pointers and links related to this FAQ

  Windows own command-line reference also: hh C:\WINDOWS\Help\ntcmds.chm
  The location may vary depending your particular configuration.
  If so, try the included WHEREIS.CMD script.

  xx) How do I control echoing in batch files? (Walter Briscoe)
  http://groups.google.com/group/comp.archives.ms-windows.discuss/msg/534d2e122c3f88b6

  Oct 28 2004 Dave Jenkins in
  Jan 11 2005 David Devore in
  ftp://garbo.uwasa.fi/pc/pd2/tspost28.zip
  tspost28.zip Information email + postings, from 19-Sep-00 to ...

More generally:
  Miscellaneous questions, information and comments about Timo's
  programs etc.  http://lipas.uwasa.fi/~ts/garbo.html#faqtimo

 ftp://garbo.uwasa.fi/pc/pd2/tspost00.zip
 Index for Timo's FAQs and Information email + postings

 ftp://garbo.uwasa.fi/pc/pd2/tspost28.zip
 Information email + postings, from 19-Sep-00 to ...

Newsgroups (here in the Google format) including
  http://www.google.com/groups?group=alt.msdos.batch.nt
  http://www.google.com/groups?group=microsoft.public.win2000.cmdprompt.admin
For more on newsgroups, see e.g.
  http://lipas.uwasa.fi/~ts/http/news.html#programming
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:21 2011
Subject: 22) How do I capture the current folder name into a variable?
Date: Mon, 31 Jan 2011 01:00:21
From: ts@uwasa.fi (Timo Salmi)

In XP this is a no-brainer because %CD% returns the current directory
string. Thus, for example
  @echo off & setlocal enableextensions
  echo %cd%
  echo %cd:~0,2%
  for /f "tokens=* delims=" %%f in ('echo %cd%') do (
    echo %%~df %%~pf %%~nf)
  endlocal & goto :EOF
The output might be e.g. C:\_D\TEST>cmdfaq
  C:\_D\TEST
  C:
  C: \_D\ TEST

As a demonstration of the current folder usage consider the following
little snippet
  @echo off & setlocal enableextensions
  set currdir_=%cd%
  pushd %currdir_%
  cd
  c:
  cd \Documents and Settings
  cd
  popd
  cd
  endlocal & goto :EOF
The ouput could be e.g. C:\_D\TEST>cmdfaq
  C:\_D\TEST
  C:\Documents and Settings
  C:\_D\TEST

or another take of the code
  @echo off & setlocal enableextensions
  set currdir_=%cd%
  pushd %currdir_%
  cd
  cd /d C:\Documents and Settings
  cd
  popd
  cd
  endlocal & goto :EOF

Note that the quote (") delimiters are not needed in here and have
hence been omitted. They could have been used, of course.

Also note that the following two expressions mean diffirent things
  @echo off & setlocal enableextensions
  echo %cd%
  echo %~dp0
  endlocal & goto :EOF
The output might be e.g.
  C:\_M>c:\_d\test\cmdfaq
  C:\_M
  c:\_D\TEST\
The former (C:\_M) is the current folder, the latter (c:\_D\TEST\) the
folder of the script called.

References/Comments:
  hh ntcmds.chm::/ntcmds_shelloverview.htm
  hh ntcmds.chm::/chdir.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:23 2011
Subject: 23) How do I get the n'th, the first and the last line of a text file?
Date: Mon, 31 Jan 2011 01:00:23
From: ts@uwasa.fi (Timo Salmi)

Assume the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4 ""

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

The easiest solution is to use SED
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  set Nth=2
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  sed -n %Nth%p "%myfile_%"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 2 &()[]{}^=;!'+,`~
which will give you any line you set, like the first line Nth=1. For
getting the last line with sed see Item #69.

The renaming to a SFN-format is needed when the SED version usually
assumed in this FAQ is used. However, if the GnuWin32 SED (let us call
it here UNXSED for distinction) is used, then the LFN/SFN file name
conversion is not needed.

  @echo off & setlocal enableextensions
  set N1=2
  set N2=6
  unxsed -n %N1%,%N2%p "My test file.txt"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4 ""

  line 6 Line 5 is empty!

With GnuWin32 G(nu)AWK the generic solution is
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  set N1=2
  set N2=6
  unxgawk "(NR>=%N1%) && (NR>=%N2%) {printf \"%%s\n\",$0}" "%myfile_%"
  endlocal & goto :EOF

To get the first line with G(nu)AWK use
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  unxgawk "NR==1 {printf \"%%s\n\",$0}" "%myfile_%"
  endlocal & goto :EOF

To get the last line with G(nu)AWK use
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  unxgawk "END{print}" "%myfile_%"
  endlocal & goto :EOF
Simple as that!

What about getting all but the last line of a file? With SED
  @echo off & setlocal enableextensions
  type "My test file.txt"|sed "$d"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4 ""

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~

Then about getting all but the last three lines of a file? With SED
  @echo off & setlocal enableextensions
  type "My test file.txt"|sed -e :a -e "$d;N;2,3ba" -e "P;D"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4 ""

  line 6 Line 5 is empty!

A Visual Basic aided command line script solution can be used for a
generic solution to output the lines of a text file starting from n1
and ending with n2. It does not have the empty lines discrepancy
problem of a straight script to be discussed later on.
  @echo off & setlocal enableextensions
  ::
  :: Your parameters
  set myfile_=My test file.txt
  set n1=2
  set n2=6
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" %n1% %n2% < "%myfile_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  set n = WScript.Arguments 'VBS
  n1 = Int(n(0)) 'VBS
  n2 = Int(n(1)) 'VBS
  '
  i = 0 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    i = i + 1 'VBS
    If i > n2 Then Exit Do 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    If i >= n1 Then 'VBS
      WScript.StdOut.WriteLine str 'VBS
    End If 'VBS
  Loop 'VBS

The output will be
  C:\_D\TEST>cmdfaq
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4 ""

  line 6 Line 5 is empty!
or with n1=1 and n2=1
  C:\_D\TEST>cmdfaq
  line 1
For getting the last line with VBS see Item #69.

Next the question arises what can be do with a pure script without
aids such as VBS or sed. For one solution see the below. (For the
first line one would naturally just set the line number as 1).
  @echo off
  setlocal enableextensions
  ::
  :: Choose the test file
  set myfile_=My test file.txt
  ::
  :: Get e.g. the second line.
  set Nth=2
  call :ProcGetLine "%myfile_%" %Nth%
  ::
  :: Another test. Get the last line
  call :ProcGetLastLine "%myfile_%" getLine
  echo %getLine%
  endlocal & goto :EOF
  ::
  ::===============================================================
  :ProcGetLine FileName LineNro returnText
  setlocal enableextensions disabledelayedexpansion
  set /a skip_=%2-1
  if %2 GTR 1 goto _notFirst
  for /f "tokens=* delims=" %%r in (
    'type "%~1"') do (
      echo.%%r
      endlocal & goto :EOF)
  :_notFirst
  for /f "tokens=* skip=%skip_% delims=" %%r in (
    'type "%~1"') do (
      echo.%%r
      endlocal & goto :EOF)
  ::
  ::===============================================================
  :ProcGetLastLine FileName returnText
  setlocal enableextensions disabledelayedexpansion
  for /f "tokens=* delims=" %%r in ('type "%~1"') do (
    set return_=%%r)
  endlocal & set "%~2=%return_%" & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 2 &()[]{}^=;!'+,`~
  line 9

However, such a pure batch solution can be confusing because of any
empty lines and also because of the special characters if one is not
careful. For example if one sets Nth=5 one gets
  C:\_D\TEST>cmdfaq
  line 6 Line 5 is empty!
and if one sets Nth=6 one gets exactly the same! The for's skip is
obviously out of synch.

There are other pure script options (but with similar problems) like
  @echo off & setlocal enableextensions
  ::
  :: Choose the test file
  set myfile_=My test file.txt
  ::
  :: Special get the first line of a file
  set /p line_=<"%myfile_%"
  echo %line_%
  ::
  :: Special get the last file of a file
  for /f "delims=" %%r in ('type "%myfile_%"') do set line_=%%r
  echo %line_%
  ::
  :: Special get the Nth line
  for %%f in ("%temp%\mytemp.txt") do if exist %%f del %%f
  set /a n_=5-1
  for /f "skip=%n_% delims=" %%r in (
    'type "%myfile_%"') do echo %%r>>"%temp%\mytemp.txt"
  set /p line_=<"%temp%\mytemp.txt"
  echo %line_%
  ::
  :: Clean up
  for %%f in ("%temp%\mytemp.txt") do if exist %%f del %%f
  endlocal & goto :EOF

The output will be
C:\_D\TEST>cmdfaq
  line 1
  line 9
  line 6 Line 5 is empty!
It gets worse, though. If one tries to get the second line
  line 2 &()[]{}^=;!'+,`~
the method breaks down
  C:\_D\TEST>cmdfaq
  ) was unexpected at this time.

Using Phil Robyn's referenced (see at end), faster solution we would
have
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f %%a in ('find /v /c "" ^< "%myfile_%"') do (
    set /a linecount=%%a)
  set /a linecount-=1
  for /f "tokens=*" %%a in (
    'more /e +%linecount% "%myfile_%"') do (
      set last_line=%%a)
  echo %last_line%
  endlocal & goto :EOF
Unfortunately, also Phil's method is suspectible to breaking down.

Alternatively, the more straight-forward
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  set myfile_=My test file.txt
  ::
  set /a GetLineNumber=5
  for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
    set /a LineCount_+=1
    if !LineCount_! EQU %GetLineNumber% set line_=%%r)
  echo %line_%
  ::
  endlocal & goto :EOF
The output is
  C:\_D\TEST>cmdfaq
  line 6 Line 5 is empty
The same problems remain, though.

So far so good(?), but one question remains, especially if the text
file is big. Which is the fastest (or fast enough) method. This aspect
has been worked out by Phil Robyn.
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  set myfile_=My test file.txt
  ::
  :: Which line?
  set /a GetLineNumber=6
  ::
  :: Perform the actual task (Due to Phil Robyn)
  set /a StartAt = GetLineNumber - 1
  more /e +%StartAt% "%myfile_%"<"%temp%\mytemp.txt"
  set /p Nth_line=<"%temp%\mytemp.txt"
  ::
  :: Show the result (note the . right after echo for empty lines)
  echo.%Nth_line%
  ::
  :: Clean up
  for %%f in ("%temp%\mytemp.txt") do if exist %%f del %%f
  endlocal & goto :EOF

The output is
  C:\_D\TEST>cmdfaq
  line 6 Line 5 is empty
The same problems still linger, though, if you insist on a pure script
solution.

> May I have idea how can I remove the line and one line above if the
> char. was matched?

You might wish to study and run the following example code
  @echo off & setlocal enableextensions
  ::
  :: Make a test file
  set testfile=C:\_M\MyTest.txt
  for %%f in ("%testfile%") do if exist %%f del %%f
  for /L %%i in (1,1,3) do echo This is row 0%%i>>"%testfile%"
  echo.>>"%testfile%"
  for /L %%i in (5,1,9) do echo This is row 0%%i>>"%testfile%"
  rem type "%testfile%"
  ::
  set targetString=row 07
  ::
  :: Get the line number of the target string
  for /f "tokens=1 delims=:" %%a in ('
    findstr /n /c:"%targetString%" "%testfile%"') do (
      set lineNber=%%a)
  ::
  set /a n1=%lineNber%-2
  sed -n 1,%n1%p "%testfile%"
  set /a n2=%lineNber%+1
  sed -n %n2%,$p "%testfile%"
  ::
  for %%f in ("%testfile%") do if exist %%f del %%f
  endlocal & goto :EOF

The test file is
  This is row 01
  This is row 02
  This is row 03

  This is row 05
  This is row 06
  This is row 07
  This is row 08
  This is row 09

The output is
  This is row 01
  This is row 02
  This is row 03

  This is row 05
  This is row 08
  This is row 09

1) The solution avoids the empty line catch common in pure batches.
2) If there are several matches, the last one (and the last one only)
   counts.

The SED deleting lines in the above could also be written as
  set /a n1=%lineNber%-1
  set /a n2=%lineNber%
  <"%testfile%" sed %n1%,%n2%d
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:24 2011
Subject: 24) How do I get the m'th item on the n'th line of a text file?
Date: Mon, 31 Jan 2011 01:00:24
From: ts@uwasa.fi (Timo Salmi)

The current question can be considered a refinement of getting the n'
th line which was considered in the previous Item #23. It is suggested
that you first peruse that item.

Assume the following LFN-type test file: "My test file.txt"
  word11 word12 word13 word14
  word21 word22 "word23" (word24)
  word31 word32 "word33" (word34)
  word41 word42 "word43" (word44)
  word51 word52 "word53" (word54)
  word61 word62 "word63" (word64)
  word71 word72 "word73" (word74)
  word81 word82 "word83" (word84)
  word91 word92 "word93" (word94)

A pure script solution, but the the poison character and empty line
problems (c.f. Item #23).
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  set n=5
  set m=3
  call :ProcGetLine "%myfile_%" %n% getLine
  for /f "tokens=%m%" %%? in ("%getLine%") do echo %%?
  endlocal & goto :EOF
  ::
  ::===============================================================
  :ProcGetLine FileName LineNro returnText
  setlocal enableextensions
  set return_=
  if %2 GTR 1 goto _notFirst
  for /f "tokens=* delims=" %%r in ('type %1') do (
    if not defined return_ set return_=%%r)
  endlocal & set "%~3=%return_%" & goto :EOF
  :_notFirst
  set lineNro_=%2
  set /a lineNro_-=1
  for /f "tokens=* skip=%lineNro_% delims=" %%r in ('type %1') do (
    if not defined return_ set return_=%%r)
  endlocal & set "%~3=%return_%" & goto :EOF
Since the fifth line in "My test file.txt" is
  word51 word52 "word53" (word54)
the output will be
  C:\_D\TEST>cmdfaq
  "word53"

Getting the characters on line 5 starting from the third ending with
the eleventh characters would be easy: Replace
  for /f "tokens=%m%" %%? in ("%getLine%") do echo %%?
with
  echo.%getLine:~2,9%
Note, however, the slight complication that the first argument starts
from zero and the second is the number of characters. Also note the
point (.) after the echo to prevent a potential "ECHO is off."
message. The output with, ruler indication lines added for clarity, is
  D:\TEST>cmdfaq
  123456789 123456789 123456789
    word51 word52 "word53" (word54)
  word51 w

Another case:
> I have strings such as these:
>   'HELLO-1039-4019-3929'
>   'YES-1930-4910-4939'
> with a variable number of characters before the first hyphen. I'd
> like my command file to parse out and return to me the string
> 'HELLO' or 'YES': whatever exists before the first hyphen. Can
> someone point me in the right direction of how to do this? Thanks
> much.

  @echo off & setlocal enableextensions
  ::
  :: Make a test file
  echo HELLO-1039-4019-3929 > mytest.txt
  echo YES-1930-4910-4939 >> mytest.txt
  ::
  ::
  for /f "tokens=1 delims=-" %%a in ('type mytest.txt') do (
    echo %%a
  )
  ::
  :: Clean up
  for %%f in (mytest.txt) do if exist %%f del %%f
  endlocal & goto :EOF
The output:
  C:\_D\TEST>cmdfaq
  HELLO
  YES

Return to the original task. With G(nu)AWK we get a more tolerant
solution
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  set n=5
  set m=3
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  gawk 'NR==%n% {printf "%%s\n",$%m%}' "%myfile_%"
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  "word53"
The renaming to a SFN-format (%%~sf) is needed when the G(nu)awk
version usually assumed in this FAQ is used.

References/Comments:
 http://www.google.com/groups?selm=432b81fb%240%2411615%249b536df3%40news.fv.fi
 http://www.google.com/groups?selm=dl4tc5%24ge4%242%40haavi.uwasa.fi
 http://www.google.com/groups?selm=dl560u%24jkl%242%40haavi.uwasa.fi
 http://www.google.com/groups?selm=43ed7935%240%2424104%249b536df3%40news.fv.fi
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:25 2011
Subject: 25) How can I quote with e.g. "> " an entire message?
Date: Mon, 31 Jan 2011 01:00:25
From: ts@uwasa.fi (Timo Salmi)

Assume the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4 ""

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

A third party solution is to use G(nu)AWK or SED. With G(nu)AWK
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  gawk '{printf "> %%s\n",$0}' "%myfile_%"
  endlocal & goto :EOF
The output is
  C:\_D\TEST>cmdfaq
  > line 1
  > line 2 &()[]{}^=;!'+,`~
  > line 3 &lt;&gt;
  > line 4 ""
  >
  > line 6 Line 5 is empty!
  > line 7
  > line 8 &()[]{}^=;!'+,`~
  > line 9
The renaming to a SFN-format is needed when the G(nu)AWK or SED
versions usually assumed in this FAQ are used.

With SED
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  sed -e "s/^/> /" "%myfile_%"
  endlocal & goto :EOF
Again, the output is
  C:\_D\TEST>cmdfaq
  > line 1
  > line 2 &()[]{}^=;!'+,`~
  > line 3 &lt;&gt;
  > line 4 ""
  >
  > line 6 Line 5 is empty!
  > line 7
  > line 8 &()[]{}^=;!'+,`~
  > line 9

A Visual Basic aided command line script solution also applies (and
gives exatcly the same output).
  @echo off & setlocal enableextensions
  ::
  :: Your message file
  set myfile_=My test file.txt
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "> " < "%myfile_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  set n = WScript.Arguments 'VBS
  quoteStr = n(0) 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    WScript.StdOut.WriteLine quoteStr & str 'VBS
  Loop 'VBS
The output is
  C:\_D\TEST>cmdfaq
  > line 1
  > line 2 &()[]{}^=;!'+,`~
  > line 3 &lt;&gt;
  > line 4 ""
  >
  > line 6 Line 5 is empty!
  > line 7
  > line 8 &()[]{}^=;!'+,`~
  > line 9

How about a pure script?
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Your parameters
  set myfile_=My test file.txt
  ::
  :: Use "> " as the quote character
  for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
    echo ^> %%r)
  endlocal & goto :EOF
The output is
  > line 1
  > line 2 &()[]{}^=;!'+,`~
  > line 3 <>
  > line 4 ""
  > line 6 Line 5 is empty!
  > line 7
  > line 8 &()[]{}^=;!'+,`~
  > line 9
Note the difference. Line five, that is the empty line is skipped by
the pure script.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:26 2011
Subject: 26) How do I get the length of a string into a variable?
Date: Mon, 31 Jan 2011 01:00:26
From: ts@uwasa.fi (Timo Salmi)

There are many variations to get a string's length
  @echo off & setlocal enableextensions
  set testString_=This is a test string
  call :GetStrLength "%testString_%" length_
  echo 123456789 123456789 123456789
  echo.%testString_%
  echo Length = %length_%
  goto :EOF
  endlocal & goto :EOF
  ::
  ::===============================================================
  :: Subroutine: Return the length of a string
  :GetStrLength string count
  setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (endlocal & set "%2=0" & goto :EOF)
  set s=%~1
  for /L %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set charCount=%%c
    )
  set /a charCount+=1
  endlocal & set "%2=%charCount%" & goto :EOF

The output is
  C:\_D\TEST>cmdfaq
  123456789 123456789 123456789
  This is a test string
  Length = 21
If there are leading or trailing blanks in the string they are
included, as they logically should.

Alternatively
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Get a test string
  if "%~1"=="" (
    set s=This is a test string
    ) else (
    set s=%*
    )
  ::
  :: Get the length of the quoted string assuming a max of 255
  set charCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c!
    if defined si set /a charCount+=1)
  if %charCount% EQU 256 set charCount=0
  echo The length of "%s%" is %charCount% characters
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq Hello World!
  The length of "Hello World" is 11 characters
Note the (undesirable) effect of the ! character. The length of "Hello
World!" is 12 characters.
As for %* "the %* batch parameter is a wildcard reference to all the
arguments, not including %0, that are passed to the batch file".

A Visual Basic Script (VBScript) aided command line script solution
  @echo off & setlocal enableextensions disabledelayedexpansion
  set testString_=This is a test string!
  call :GetStrLength "%testString_%" length_
  echo 123456789 123456789 123456789
  echo.%testString_%
  echo Length = %length_%
  goto :EOF
  endlocal & goto :EOF
  ::
  ::===============================================================
  :: Subroutine: Return the length of a string using VBScript
  :GetStrLength
  setlocal enableextensions
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Len("%~1")
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%temp%\tmp$$$.vbs"') do set return_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & set "%~2=%return_%" & goto :EOF

The output is
  C:\_D\TEST>cmdfaq
  123456789 123456789 123456789
  This is a test string!
  Length = 22

One method for getting the length of the string is to truncate a
copy of the string one character at a time (from the front) until
the copy becomes undefined, while at the same time keeping score of
the number of steps required. The possibility of an already empty
string must be taken into account.

  @echo off
  setlocal enableextensions
  set testString_=This is a test string!
  call :GetStrLength %testString_%
  echo 123456789 123456789 123456789
  echo.%testString_%
  echo Length = %length_%
  goto :EOF
  ::
  ::===============================================================
  :GetStrLength
  setlocal enableextensions
    set rest_=%*
    set /a count_=0
    if not defined rest_ (set /a count_=-1 & set rest_=X)
    :_loop
      set /a count_+=1
      set rest_=%rest_:~1%
      if defined rest_ goto :_loop
  endlocal & set length_=%count_% & goto :EOF
The output:
  D:\TEST>cmdfaq
  123456789 123456789 123456789
  This is a test string!
  Length = 22

Yet another option is to write the string into a temporary file and
get that file's size (minus 2).
  @echo off & setlocal enableextensions
  set testString_=This is a test string!
  echo %testString_%>"%temp%\length.tmp"
  for %%f in ("%temp%\length.tmp") do set length_=%%~zf
  for %%f in ("%temp%\length.tmp") do if exist %%f del %%f
  set /a length_ = %length_% - 2
  echo The length of "%testString_%" is %length_%
  endlocal & goto :EOF
The output is
  D:\TEST>cmdfaq
  The length of "This is a test string" is 22

Or
  @echo off & setlocal enableextensions
  set testString_=This is a test string!
  0>nul 1>"%temp%\cmdfaq.tmp" set /p var_="%testString_%"
  for %%f in ("%temp%\cmdfaq.tmp") do (
    set length_=%%~zf
    if exist %%f del %%f)
  echo The length of "%testString_%" is %length_%
  endlocal & goto :EOF

The output is again
  D:\TEST>cmdfaq
  The length of "This is a test string!" is 22

A G(nu)AWK solution to the problem is
  @echo off & setlocal enableextensions
  set testString_=This is a test string!
  if not exist c:\mytemp mkdir c:\mytemp
  echo %testString_%|unxgawk^
    "{printf\"@set length_=%%s\n\",length()}"^
    >c:\mytemp\length$$.cmd
  call c:\mytemp\length$$.cmd
  echo 123456789 123456789 123456789
  echo.%testString_%
  echo Length = %length_%
  set length_=
  del c:\mytemp\length$$.cmd
  rmdir c:\mytemp
  endlocal & goto :EOF
The output is
  C:\_D\TEST>cmdfaq
  123456789 123456789 123456789
  This is a test string!
  Length = 22

A FINDSTR option, based on a Usenet posting by Tom Lavedas
  @echo off & setlocal enableextensions
  set testString_=This is a test string!
  for /f "tokens=1 delims=:" %%a in (
    '^(echo.%testString_%^&echo AnUncommonString^)^|
      findstr /o "AnUncommonString"'
    ) do set /a length_=%%a-3
  echo.%testString_%
  echo Length = %length_%
  endlocal & goto :EOF
The output is
  C:\_D\TEST>cmdfaq
  This is a test string!
  Length = 22

Another rendition of a FINDSTR solution
  @echo off & setlocal enableextensions
  set testString_=This is a test string!
  for /f "delims=:" %%a in ('
    ^(echo."%testString_%"^& echo.^)^|findstr /o .'
    ) do set /a length_=%%a-5
  echo The length of "%testString_%" is %length_%
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=ffd662ea.0411270916.3f78c102%40posting.google.com
 http://www.google.com/groups?selm=u7diq0hfhiolt3usvqq2grfaqb2u6olmr1%404ax.com
 http://www.google.com/groups?selm=8ec15f40-d2d6-4427-8d0c-e9dae1a32281%40j32g2000yqh.googlegroups.com
 http://www.google.com/groups?selm=80411d11-c02f-43a7-9e14-f51a7271e33b%40u7g2000yqm.googlegroups.com
 http://www.google.com/groups?selm=35e1cc34-494e-49fe-bb85-92b90d08263f%40c3g2000yqd.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:27 2011
Subject: 27) How can I remove all the blank lines from a text file?
Date: Mon, 31 Jan 2011 01:00:27
From: ts@uwasa.fi (Timo Salmi)

Assume e.g. the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4


  line 7 Lines "5" and "6" are blank!
  line 8
  line 9 &()[]{}^=;!'+,`~

Several options are available. One pure script solution would be
  @echo off & setlocal enableextensions disabledelayedexpansion
  for %%f in ("myfileNoBlanks.txt") do if exist %%f del %%f
  for /f "delims=" %%r in ('type "My test file.txt"') do echo.%%r>>"myfileNoBlanks.txt"
  endlocal & goto :EOF
The contents of myfileNoBlanks.txt will be
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4
  line 7 Lines "5" and "6" are blank!
  line 8
  line 9 &()[]{}^=;!'+,`~

Using SED Stream EDitor:
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  sed "/^$/d" "%myfile_%"
  endlocal & goto :EOF

Using the native FINDSTR is equally easy. This regular expression
solution would appear to be the best, natural option. Either from the
command line or from within a script
  findstr /v "^$" "My test file.txt"
Incidentally, note the difference with the literal option
  findstr /v /c:"^$" "My test file.txt"
which, expectedly, will not solve the problem at hand.

Likewise, GAWK could be used
  @echo off & setlocal enableextensions
  <"My test file.txt" gawk '{if(length($0)!=0)printf"%%s\n",$0}'
  endlocal & goto :EOF
or
@echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  gawk 'length()!=0' "%myfile_%"
  endlocal & goto :EOF
or
  @echo off & setlocal enableextensions
  unxgawk "{if(length()>0)printf\"%%s\n\",$0}" "My test file.txt"
  endlocal & goto :EOF

If you wish to also define as an empty line a line that has nothing
but blanks or tabs on it, then use
  @echo off & setlocal enableextensions
  <"My test file.txt" sed "/^[\x09 ]*$/d"
  endlocal & goto :EOF
or
  @echo off & setlocal enableextensions
  <"My test file.txt" gawk 'NF!=0'
  endlocal & goto :EOF

OK, but what if you wish to remove all the lines that are two
characters or shorter. Or put in another way, you want to get all
the lines that are at least 3 characters long. This is one way how
to do it
  @echo off & setlocal enableextensions
  <"My test file.txt" gawk '{if(index(2-length(),"-"))printf"%%s\n",$0}'
  endlocal & goto :EOF
or in abbreviated format
  @echo off & setlocal enableextensions
  <"My test file.txt" gawk 'index(2-length(),"-")'
  endlocal & goto :EOF

Assume a slightly changed "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>

  5
  06
  line 7 Line "4" is blank, "5" and "6" are short!
  line 8
  line 9 &()[]{}^=;!'+,`~

A pure command-line script solution is possible
  @echo off & setlocal enableextensions
  echo ^^$>"%temp%\findstr.tmp"
  echo ^^.$>>"%temp%\findstr.tmp"
  echo ^^..$>>"%temp%\findstr.tmp"
  findstr /v /g:"%temp%\findstr.tmp" "My test file.txt"
  for %%f in ("%temp%\findstr.tmp") do (
    if exist %%f del %%f)
  endlocal & goto :EOF
The output
  C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 7 Line "4" is blank, "5" and "6" are short!
  line 8
  line 9 &()[]{}^=;!'+,`~

For demonstration, the problem can also be solved with a Visual
Basic Script (VBScript) aided command line script. Use "Len(str) >
0" if the original task is being solved instead of the "two
characters or shorter".
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_="%temp%\tmp$$$.vbs"
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo %vbs_% < "My test file.txt"
  ::
  :: Clean up
  for %%f in (%vbs_%) do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'The Visual Basic Script
  '
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    If Len(str) > 2 Then WScript.StdOut.WriteLine str 'VBS
  Loop 'VBS
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:28 2011
Subject: 28) How to convert a file written in IBM PC characters into LATIN1?
Date: Mon, 31 Jan 2011 01:00:28
From: ts@uwasa.fi (Timo Salmi)

For more instructive and fuller documentation his item is much better
seen at http://www.netikka.net/tsneti/info/tscmd028.htm

This is another task, which is best suited for SED, the Stream
EDitor.

  @echo off
  setlocal enableextensions
  ::
  :: Covert IBM PC characters into LATIN1 characters
  :: Requires SED.EXE
  ::
  :: Make a test file with PC characters
  echo This is a test file in Finnish (which uses Scandinavian characters)>testin.txt
  echo Tm on testitiedosto ksten testaamiseksi.>>testin.txt
  echo Lis:  >>testin.txt
  echo >>testin.txt
  ::
  :: Optionally, create a SED command file
  echo.y//\xE5\xE4\xF6\xFC\xE9\xE7\xE6\xF1\xC5\xC4\xD6\xDC\xC9\xC7\xC6\xD1/>"%TEMP%\IBM2LAT1.SED"
  ::
  :: Do the conversion
  sed -f"%TEMP%\IBM2LAT1.SED" testin.txt > testout.txt
  ::
  :: See that the result is what one expected
  notepad testout.txt
  ::
  :: Clean up
  for %%f in ("%TEMP%\IBM2LAT1.SED" testin.txt testout.txt) do if exist %%f del %%f
  endlocal & goto :EOF

A catch if you are using ftp://garbo.uwasa.fi/pc/unix/sed15x.zip
as in this FAQ. The file names must be in the SFN 8+3 format. If we
use the GnuWin32 sed.exe instead, that will not pose a problem. In
below, the sed.exe has been renamed as unxsed.exe
  @echo off & setlocal enableextensions
  ::
  :: Covert IBM PC characters into LATIN1 characters
  :: Requires SED.EXE (renamed here to UNXSED.EXE)
  ::
  :: Make a test file with PC characters
  echo This is a test file in Finnish (which uses Scandinavian characters)>"testin.txt"
  echo Tm on testitiedosto ksten testaamiseksi.>>"testin.txt"
  echo Lis:  >>"testin.txt"
  echo >>"testin.txt"
  ::
  :: Another way to build the SED command file
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set sedcmd=%temp_%\sedcmd.tmp
  echo s//\xE5/g >  "%sedcmd%"
  echo s//\xE4/g >> "%sedcmd%"
  echo s//\xF6/g >> "%sedcmd%"
  echo s//\xFC/g >> "%sedcmd%"
  echo s//\xE9/g >> "%sedcmd%"
  echo s//\xE7/g >> "%sedcmd%"
  echo s//\xE6/g >> "%sedcmd%"
  echo s//\xF1/g >> "%sedcmd%"
  echo s//\xC5/g >> "%sedcmd%"
  echo s//\xC4/g >> "%sedcmd%"
  echo s//\xD6/g >> "%sedcmd%"
  echo s//\xDC/g >> "%sedcmd%"
  echo s//\xC9/g >> "%sedcmd%"
  echo s//\xC7/g >> "%sedcmd%"
  echo s//\xC6/g >> "%sedcmd%"
  echo s//\xD1/g >> "%sedcmd%"
  ::
  :: Do the conversion
  unxsed --text -f"%sedcmd%" "testin.txt" > "testout.txt"
  ::
  :: See that the result is what one expected
  notepad "testout.txt"
  ::
  :: Clean up
  for %%f in ("%sedcmd%" "testin.txt" "testout.txt") do (
    if exist %%f del %%f)
  endlocal & goto :EOF

The problem can also be solved with a Visual Basic Script. VBScript
has the advantage of being a part of the original XP command
environment. On the other hand the solution is clearly more
complicated than the very simple SED solution. Anyway, first cut and
paste the following script. Name it e.g. IBM2LAT1.VBS and then call it
using

 CSCRIPT //NOLOGO "IBM2LAT1.VBS" < "MYIBM.TXT" > "MYLATIN1.TXT"

' IBM2LAT1.VBS by Prof. Timo Salmi
'
' Define the relevant characters
Const IbmChar = ""
Const Lat1Char = ""
'
' Define StandardIn and StandardOut
Dim StdIn, StdOut
Set StdIn = WScript.StdIn
Set StdOut = WScript.StdOut
'
' Convert one IBM character to Latin1
Function CharIbm2Lat1(char)
  Dim p
  p = Instr (1, IbmChar, char, 1)
  if p > 0 Then
    CharIbm2Lat1 = Mid(Lat1Char, p, 1)
  Else
    CharIbm2Lat1 = char
  End If
End Function
'
' Convert a string
Function Ibm2Lat1(str1)
  Dim str2
  For i = 1 To Len(str1)
    str2 = str2 & CharIbm2Lat1(Mid(str1,i,1))
  Next
  Ibm2Lat1 = str2
End Function
'
' Convert the input
Dim str
Do While Not StdIn.AtEndOfStream
  str = StdIn.ReadLine
  StdOut.WriteLine Ibm2Lat1(str)
Loop

It is easy to see that other, similar conversion tasks can be done
with the same methods after just some slight customization. To take
the most obvious example, consider the conversion into the other
direction:
  ' C:\_F\CMD\IBM2LAT1.VBS by Prof. Timo Salmi
  ' Usage: CSCRIPT //NOLOGO "LAT12IBM.VBS" < "MYLATIN1.TXT" > "MYIBM.TXT"
  '
  ' Define the relevant characters
  Const Lat1Char = ""
  Const IbmChar  = ""
  '
  ' Define StandardIn and StandardOut
  Dim StdIn, StdOut
  Set StdIn = WScript.StdIn
  Set StdOut = WScript.StdOut
  '
  ' Convert one IBM character to Latin1
  Function CharLat12Ibm(char)
    Dim p
    p = Instr (1, Lat1Char, char, vbBinaryCompare)
    if p > 0 Then
      CharLat12Ibm = Mid(IbmChar, p, 1)
    Else
      CharLat12Ibm = char
    End If
  End Function
  '
  ' Convert a string
  Function Lat12Ibm(str1)
    Dim str2
    For i = 1 To Len(str1)
      str2 = str2 & CharLat12Ibm(Mid(str1,i,1))
    Next
    Lat12Ibm = str2
  End Function
  '
  ' Convert the input
  Dim str
  Do While Not StdIn.AtEndOfStream
    str = StdIn.ReadLine
    StdOut.WriteLine Lat12Ibm(str)
  Loop

ANSI vs. UNICODE

There is another feature that factors in. That is how the new instance
of the Windows XP command interpreter is called. See CMD /? for the
options. Essentially
   /A Causes the output of internal commands to a pipe or file to be ANSI
   /U Causes the output of internal commands to a pipe or file to be Unicode
It appreas that /A would be the default.

Using the example of this item we could write
  @echo off & setlocal enableextensions
  ::
  :: Covert ANSI characters into UNICODE characters
  ::
  :: Make a test file with PC characters (assuming that CMD has been thus invoked)
  echo This is a test file in Finnish (which uses Scandinavian characters)>"testin.txt"
  echo Tm on testitiedosto ksten testaamiseksi.>>"testin.txt"
  echo Lis:  >>"testin.txt"
  echo >>"testin.txt"
  ::
  :: Do a conversion to Unicode (/a would be to ANSI)
  cmd /u /c type "testin.txt" > "testout.txt"
  ::
  :: See that the result is what one expected
  notepad "testout.txt"
  ::
  :: Clean up
  for %%f in ("testin.txt" "testout.txt") do if exist %%f del %%f
  endlocal & goto :EOF

However, if a TR.EXE port is not available, a Visual Basic Script
(VBScript) aided command line script can be applied:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it
  set vbs_="%temp%\tmp$$$.vbs"
  set skip=
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  cscript //nologo %vbs_%
  ::
  :: Clean up
  for %%f in (%vbs_%) do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Dim StdIn, StdOut, char, chr0 'VBS
  Set StdIn = WScript.StdIn 'VBS
  Set StdOut = WScript.StdOut 'VBS
  '
  chr0 = Chr(0) 'VBS
  Do While Not StdIn.AtEndOfStream 'VBS
    char = StdIn.Read(1) 'VBS
    If char <> chr0 Then 'VBS
      StdOut.Write char 'VBS
    End If 'VBS
  Loop 'VBS

Usage: cmdfaq < "testout.txt"

You might also find of interest the information given by Windows
Character Map C:\WINDOWS\system32\charmap.exe

References/Comments:
 http://www.microsoft.com/globaldev/reference/WinCP.mspx
 http://en.wikipedia.org/wiki/ISO_8859-1
 hh ntcmds.chm::/cmd.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:29 2011
Subject: 29) How do I drop the first two characters of a string, and so on?
Date: Mon, 31 Jan 2011 01:00:29
From: ts@uwasa.fi (Timo Salmi)

In CMD.EXE scripts dropping the first two characters is very simple:
  @echo off & setlocal enableextensions
  setlocal enableextensions
  set test_=This is a test
  echo %test_:~2%
  endlocal & goto :EOF
The output is
  is is a test

As we have seen, the base syntax for extracting a substring is
%var_:Start,Count% where the first character is designated 0 (zero)
not one. Thus
  @echo off
  setlocal enableextensions
  set test_=This_is_a_test
  echo %test_:~2,5%
  endlocal & goto :EOF
gives
  is_is

Now, how about dropping the LAST two characters?
  @echo off
  setlocal enableextensions
  set test_=This_is_a_test
  echo %test_:~0,-2%
  endlocal & goto :EOF
gives
  This_is_a_te

The above drops the last two characters, but reversing how does one
get them?
  @echo off & setlocal enableextensions
  setlocal enableextensions
  set test_=This is a test
  echo %test_:~-2%
  endlocal & goto :EOF
gives
  st

Obviously there are more potential combinations, but this is how the
basics go. For more see CMD1DEMO.CMD "A CMD syntax selection demo".
Also see Item #44.

For the sake of comparison let's demonstrate solving dropping the
first two characters with a Visual Basic aided script (VBScript):
  @echo off & setlocal enableextensions
  setlocal enableextensions
  set test_=This is a test
  echo %test_%
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Mid("%test_%",3)
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%temp%\tmp$$$.vbs"') do set test_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  echo %test_%
  endlocal & goto :EOF
The output is
  C:\_D\TEST>cmdfaq
  This is a test
  is is a test

With G(nu)AWK:
  @echo off & setlocal enableextensions
  setlocal enableextensions
  set test_=This is a test
  echo %test_%
  gawk 'BEGIN{printf "set test_=%%s\n",substr("%test_%",3)}'>"%temp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  echo %test_%
  endlocal & goto :EOF

References/Comments:
 SET /?
 http://www.google.com/groups?selm=c7d02vo2br8vmqtcagq7grttero4crnphd%404ax.com
 http://msdn2.microsoft.com/en-us/library/t0aew7h6(VS.85).aspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:30 2011
Subject: 30) Can one calculate the difference between two times in a script?
Date: Mon, 31 Jan 2011 01:00:30
From: ts@uwasa.fi (Timo Salmi)

Yes, one can:
  @echo off & setlocal enableextensions
  set /a diffSec=60*60*%4+60*%5+%6-(60*60*%1+60*%2+%3)
  if %diffSec% LSS 0 set /a diffSec=%diffSec%+24*60*60
  ::
  set /a h=(%diffSec%/3600)
  set /a m=(%diffSec%/60)-60*%h%
  set /a s=%diffSec%-60*(%diffSec%/60)
  ::
  echo hrs=%h% min=%m% sec=%s%
  ::
  endlocal & goto :EOF
For example
  D:\TEST>cmdfaq 12 13 56 17 4 57
  hrs=4 min=51 sec=1

Next apply to get the duration of a task. Use Visual Basic Script
(VBScript) aided command line scripting for better locale independence.
  @echo off & setlocal enableextensions
  call :GetTime hh1_ mn1_ ss1_
  echo hh1_=%hh1_% mn1_=%mn1_% ss1_=%ss1_%
  rem Do whatever, like delay for demonstration:
  ping -n 3 127.0.0.1>nul
  call :GetTime hh2_ mn2_ ss2_
  echo hh2_=%hh2_% mn2_=%mn2_% ss2_=%ss2_%
  call :TimeDiff %hh1_% %mn1_% %ss1_% %hh2_% %mn2_% %ss2_% hh_ mn_ ss_
  echo hh_=%hh_% mn_=%mn_% ss_=%ss_%
  endlocal & goto :EOF
  ::
  ::=============================================================
  :GetTime
  setlocal enableextensions
  set vbs_=%temp%\tmp.vbs
  echo FixedTime=Time>"%vbs_%"
  echo WScript.Echo Hour(FixedTime) ^&" "^& ^
                    Minute(FixedTime) ^&" "^& ^
                    Second(FixedTime) >> "%vbs_%"
  for /f "tokens=1-3" %%a in ('cscript //nologo "%vbs_%"') do (
    set hh_=%%a
    set mn_=%%b
    set ss_=%%c)
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal&set "%1=%hh_%"&set "%2=%mn_%"&set "%3=%ss_%"&goto :EOF
  ::
  ::=============================================================
  :TimeDiff
  setlocal enableextensions
  set /a diffSec=60*60*%4+60*%5+%6-(60*60*%1+60*%2+%3)
  if %diffSec% LSS 0 set /a diffSec=%diffSec%+24*60*60
  set /a h=(%diffSec%/3600)
  set /a m=(%diffSec%/60)-60*%h%
  set /a s=%diffSec%-60*(%diffSec%/60)
  endlocal&set "%7=%h%"&set "%8=%m%"&set "%9=%s%"&goto :EOF
The output would be something like
  C:\_D\TEMP>cmdfaq
  hh1_=8 mn1_=11 ss1_=1
  hh2_=8 mn2_=11 ss2_=3
  hh_=0 mn_=0 ss_=2

The problem with the above is the low resolution (seconds max). We
could also use echo %time% but then we run into the problems with
localization (like where the am/pm or the 24-hour format is on).
However, for short intervals taking seconds and the hundreds of
seconds could suffice.
  @echo off & setlocal enableextensions
  call :GetTime100 hh1_ mn1_ ss1_ sh1_
  echo hh1_=%hh1_% mn1_=%mn1_% ss1_=%ss1_% sh1_=%sh1_%
  rem Do whatever, like delay for demonstration:
  ping -n 1 127.0.0.1>nul
  call :GetTime100 hh2_ mn2_ ss2_ sh2_
  echo hh2_=%hh2_% mn2_=%mn2_% ss2_=%ss2_% sh2_=%sh2_%
  call :TimeDiff100 %hh1_% %mn1_% %ss1_% %sh1_% %hh2_% %mn2_% %ss2_% %sh2_% diff_
  echo %diff_%
  endlocal & goto :EOF
  ::
  ::=============================================================
  :GetTime100
  setlocal enableextensions
  for /f "tokens=1-4 delims=:.;" %%a in ('echo %time%') do (
    set hh_=%%a
    set mn_=%%b
    set ss_=%%c
    set s100_=%%d)
  call :Trim %hh_% hh_
  call :Trim %mn_% mn_
  call :Trim %ss_% ss_
  call :Trim %s100_% s100_
  endlocal&set "%1=%hh_%"&set "%2=%mn_%"&set "%3=%ss_%"&set "%4=%s100_%"&goto :EOF
  ::
  ::=============================================================
  :Trim
  setlocal enableextensions
  echo %1|findstr [123456789]>nul
  if %errorlevel% EQU 0 (
    for /f "tokens=* delims=0 " %%a in ('echo %~1') do (
      set Return_=%%a)
    ) else (set Return_=0)
  endlocal & set "%2=%Return_%" & goto :EOF
  ::
  ::=============================================================
  :TimeDiff100
  setlocal enableextensions
  set /a diffSec=100*60*60*%5+100*60*%6+100*%7+%8-(100*60*60*%1+100*60*%2+100*%3+%4)
  if %diffSec% LSS 0 set /a diffSec=%diffSec%+24*60*60*100
  endlocal & set "%9=%diffSec%" & goto :EOF

Examples of the output
  C:\_D\TEST>cmdfaq
  hh1_=8 mn1_=55 ss1_=6 sh1_=50
  hh2_=8 mn2_=55 ss2_=8 sh2_=5
  155

  C:\_D\TEST>cmdfaq
  hh1_=8 mn1_=55 ss1_=15 sh1_=0
  hh2_=8 mn2_=55 ss2_=16 sh2_=43
  143

  C:\_D\TEST>cmdfaq
  hh1_=8 mn1_=55 ss1_=51 sh1_=30
  hh2_=8 mn2_=55 ss2_=51 sh2_=78
  48
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:31 2011
Subject: 31) How many days ago was 31.12.2002? What date it was 100 days ago?
Date: Mon, 31 Jan 2011 01:00:31
From: ts@uwasa.fi (Timo Salmi)

Days since a certain day can be calculated as follows. If the
current day is in the next year (2003) then the method effectively
gives today's annual day number.
  @echo off & setlocal enableextensions
  ::
  :: Get and show today's Julian date number
  :: Requires DATE2NUM.EXE from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
  DATE2NUM /set > "%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  set dateNumberNow=%datenum_%
  echo dateNumberNow=%dateNumberNow%
  ::
  :: Get and show the Julian date number of 31.12.2002
  DATE2NUM 31 12 2002 /set > "%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  set dateNumberThen=%datenum_%
  echo dateNumberThen=%dateNumberThen%
  ::
  :: Calculate the difference and show
  set /a ago_=%dateNumberNow% - %dateNumberThen%
  echo.
  echo 31.12.2002 was %ago_% days ago
  endlocal & goto :EOF

A screen capture could be something like
  D:\TEST>date /t
  08.12.2003

  D:\TEST>cmdfaq
  dateNumberNow=2452982
  dateNumberThen=2452640
  31.12.2002 was 342 days ago

The problem can also be solved using a Visual Basic Script (VBScript)
aided command line script:
  @echo off & setlocal enableextensions
  ::
  set day_=31
  set month_=12
  set year_=2007
  ::
  >"%temp%\tmp$$$.vbs" echo WScript.Echo DateDiff("d", DateValue("%day_%, %month_%, %year_%"), Date)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set ago_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  ::
  date /t
  echo %day_%.%month_%.%year_% was %ago_% days ago
  endlocal & goto :EOF

A screen capture could be something like
  C:\_D\TEST>cmdfaq
  03.04.2008
  31.12.2007 was 94 days ago

Note how this item opens the door for calculating how old a file is
based on its datetime stamp. This, in turn, can be utilized to solve
the frequent question "How do I delete from a folder files which are
older than a hundred days?"

Next a solution to the 100 days ago problem:
  @echo off & setlocal enableextensions
  ::
  :: Get and show today's Julian date number
  :: Requires DATE2NUM.EXE from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
  DATE2NUM /set > "%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  set dateNumberNow=%datenum_%
  echo dateNumberNow=%dateNumberNow%
  ::
  :: Subtract a hundred days
  set /a dateNumberThen=%dateNumberNow%-100
  echo dateNumberThen=%dateNumberThen%
  ::
  :: Convert it back into a date
  :: Requires NUM2DATE.EXE from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
  NUM2DATE %dateNumberThen% /set > "%mytemp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
  echo It was %ddpad_%.%mmpad_%.%yyyy_%
  endlocal & goto :EOF

The output would be something like
C:\_D\TEST>date /t
03.04.2008

C:\_D\TEST>cmdfaq
dateNumberNow=2454560
dateNumberThen=2454460
It was 25.12.2007

A Visual Basic Script (VBScript) aided command line script solution
option:
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp%\tmp$$$.vbs">"%temp%\tmp$$$.cmd"
  :: Call the command line script which the script host built
  call "%temp%\tmp$$$.cmd"
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  :: Demonstrate the result
  echo dtoday_=%dtoday_%
  echo ago100_=%ago100_%
  echo fut100_=%fut100_%
  endlocal & goto :EOF
  '
  DateNow=Date                                    'VBS
  wscript.echo "@set dtoday_=" & Int(DateNow)     'VBS
  wscript.echo "@set ago100_=" & Int(DateNow-100) 'VBS
  wscript.echo "@set fut100_=" & Int(DateNow+100) 'VBS
The output might be something like
  D:\TEST>cmdfaq
  dtoday_=19.02.2005
  ago100_=11.11.2004
  fut100_=30.05.2005

There are different ways of writing this Visual Basic Script (
VBScript) aided command line script:
  @echo off & setlocal enableextensions
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Int(Date)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set dtoday_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Int(Date-100)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set ago100_=%%a
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Int(Date+100)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set fut100_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  :: Demonstrate the result
  echo dtoday_=%dtoday_%
  echo ago100_=%ago100_%
  echo fut100_=%fut100_%
  endlocal & goto :EOF

Note how this item opens the door for identifying files which have
been made a given number of days ago. Or identifying how old a file
is. The latter task is solved in FILEAGE.CMD included in tscmd.zip.

One usage of the results of this item is constructing an XCOPY
parameter. In XCOPY /D:date "Copies files changed on or after the
specified date". E.g. for the previous thirty days you could have
  set xcdate_=%mmpad_%-%ddpad_%-%yyyy_%
  echo xcdate_=%xcdate_%
The needed exact XCOPY date format is dependent on your "Regional
Settings".
  @echo off & setlocal enableextensions
  ::
  :: How many days back?
  set daysback_=%~1
  :: A validity test
  echo %daysback_%|findstr "[^1234567890]">nul
  if %errorlevel% EQU 0 (
    echo.
    echo Usage %~f0 DaysBack
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  for /f "usebackq tokens=1-3" %%a in (
    `cscript //nologo "%temp%\tmp$$$.vbs" "%daysback_%"`) do (
      set ddpad_=%%a
      set mmpad_=%%b
      set yyyy_=%%c)
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo %date%
  echo ddpad_=%ddpad_%
  echo mmpad_=%mmpad_%
  echo yyyy_=%yyyy_%
  set xcdate_=%mmpad_%-%ddpad_%-%yyyy_%
  echo xcdate_=%xcdate_%
  endlocal & goto :EOF
  '
  DateNow=Date 'VBS
  DateThen=CStr(Int(DateNow-WScript.Arguments.Unnamed(0))) 'VBS
  Wscript.Echo Mid(DateThen,1,2) + " " + Mid(DateThen,4,2) + " " + Mid(DateThen,7,4) 'VBS

The output might be for example
  D:\TEST>D:\TEST\CMDFAQ.CMD 20
  22.08.2010
  ddpad_=02
  mmpad_=08
  yyyy_=2010
  xcdate_=08-02-2010

A VBS example with yesterday's date
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp%\tmp$$$.vbs">"%temp%\tmp$$$.cmd"
  :: Call the command line script which the script host built
  call "%temp%\tmp$$$.cmd"
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  :: Demonstrate the result
  echo %date%
  echo ddpad_=%ddpad_%
  echo mmpad_=%mmpad_%
  echo yyyy_=%yyyy_%
  endlocal & goto :EOF
  '
  DateNow=Date                                     'VBS
  Yesterday=CStr(Int(DateNow-1))                   'VBS
  wscript.echo "@set ddpad_=" & Mid(Yesterday,1,2) 'VBS
  wscript.echo "@set mmpad_=" & Mid(Yesterday,4,2) 'VBS
  wscript.echo "@set yyyy_="  & Mid(Yesterday,7,4) 'VBS
The output might be for example
  D:\TEST>cmdfaq
  19.02.2005
  ddpad_=18
  mmpad_=02
  yyyy_=2005

The problems can also be solved with original script commands only.
To get "How many days ago was 31.12.2002". Local DD.MM.YYYY date
format is assumed.
  @echo off & setlocal enableextensions
  if "%~3"=="" (
    echo Usage: %~0 DD MM YYYY
    echo No leading zeros!
    goto :EOF)
  ::
  :: Get today's date elements
  for /f "tokens=1-3 delims=./-" %%f in ('date /t') do (
    set today_=%%h%%g%%f
    set dd_=%%f
    set mm_=%%g
    set yyyy_=%%h)
  :: Omit the leading zeros and trailing spaces
  for /f "tokens=* delims=0" %%a in ('echo %dd_%') do set dd_=%%a
  for /f "tokens=* delims=0" %%a in ('echo %mm_%') do set mm_=%%a
  set yyyy_=%yyyy_:~0,4%
  ::
  :: Get the second date
  set day=%~1
  set month=%~2
  set year=%~3
  ::
  :: Get the Julian day numbers and calculate the difference
  call :JDnumber %dd_% %mm_% %yyyy_% jd1_
  call :JDnumber %day% %month% %year% jd2_
  set /a diff_=%jd1_%-%jd2_%
  ::
  :: Display the result
  echo %dd_%.%mm_%.%yyyy_%
  echo %day%.%month%.%year%
  echo Julian day numbers %jd1_% %jd2_% Difference: %diff_% days
  endlocal & goto :EOF
  ::
  :: =========================================================
  :: Subroutine: Calculate the chronological Julian Day number
  :JDnumber day month year return_
  setlocal enableextensions
  set /a a=(14-%2)/12
  set /a y=%3+4800-%a%
  set /a m=%2+12*%a%-3
  set /a return_=%1+(153*%m%+2)/5+%y%*365+%y%/4-%y%/100+%y%/400-32045
  endlocal & set "%4=%return_%" & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq 31 12 2005
  7.9.2006
  31.12.2002
  Julian day numbers 2453986 2452640 Difference: 1346 days

To get "What date it was 100 days ago?" with original script
commands only: (Also see DATEINFO.CMD)
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 DaysAgo
    goto :EOF)
  ::
  :: Get today's date elements
  for /f "tokens=1-3 delims=./-" %%f in ('date /t') do (
    set today_=%%h%%g%%f
    set dd_=%%f
    set mm_=%%g
    set yyyy_=%%h)
  :: Omit the leading zeros and trailing spaces
  for /f "tokens=* delims=0" %%a in ('echo %dd_%') do set dd_=%%a
  for /f "tokens=* delims=0" %%a in ('echo %mm_%') do set mm_=%%a
  set yyyy_=%yyyy_:~0,4%
  ::
  :: How many days back
  set daysAgo=%~1
  ::
  :: Get today's Julian day number
  call :JDnumber %dd_% %mm_% %yyyy_% dateNumberNow
  ::
  :: Subtract the given number of days
  set /a dateNumberThen=%dateNumberNow%-%daysAgo%
  ::
  :: What was the date back then
  call :JDinverse %dateNumberThen% day month year
  ::
  :: Display the result
  echo dateNumberNow =%dateNumberNow%  for %dd_%.%mm_%.%yyyy_%
  echo dateNumberThen=%dateNumberThen%  for %daysAgo% days ago
  echo %day%.%month%.%year%
  endlocal & goto :EOF
  ::
  :: =========================================================
  :: Subroutine: Calculate the chronological Julian Day number
  :JDnumber day month year return_
  setlocal enableextensions
  set /a a=(14-%2)/12
  set /a y=%3+4800-%a%
  set /a m=%2+12*%a%-3
  set /a return_=%1+(153*%m%+2)/5+%y%*365+%y%/4-%y%/100+%y%/400-32045
  endlocal & set "%4=%return_%" & goto :EOF
  ::
  :: ===============================================
  :: Subroutine: Get the date of a Julian Day number
  :JDinverse dateNumber day month year
  setlocal enableextensions
  set /a a=%1+32044
  set /a b=(4*%a%+3)/146097
  set /a c=%a%-(%b%*146097)/4
  set /a d=(4*%c%+3)/1461
  set /a e=%c%-(1461*%d%)/4
  set /a m=(5*%e%+2)/153
  set /a day=%e%-(153*%m%+2)/5+1
  set /a month=%m%+3-12*(%m%/10)
  set /a year=%b%*100+%d%-4800+%m%/10
  endlocal &set "%2=%day%" &set "%3=%month%" &set "%4=%year%" &goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq 100
  dateNumberNow =2453986  for 7.9.2006
  dateNumberThen=2453886  for 100 days ago
  30.5.2006

References/Comments:
 http://www.google.com/groups?selm=nrwFWmAneiDCFwNY%40merlyn.demon.co.uk
 http://www.google.com/groups?selm=h0e0xpLhrfcDFwBK%40merlyn.demon.co.uk
 http://www.tondering.dk/claus/cal/node3.html#SECTION003161000000000000000
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:32 2011
Subject: 32) How can I convert a decimal number to binary, octal, hexadecimal?
Date: Mon, 31 Jan 2011 01:00:32
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  set decimal_=78
  call :DecimalToBinary %decimal_% binary_
  echo Decimal %decimal_% = Binary %binary_%
  ::
  call :DecimalToOctal %decimal_% oct_
  echo Decimal %decimal_% = Octal %oct_%
  ::
  call :DecimalToHex %decimal_% hex_
  echo Decimal %decimal_% = Hexadecimal %hex_%
  endlocal & goto :EOF
  ::
  ::===============================================================
  :DecimalToBinary DecimalIn BinaryOut
  ::
  setlocal enableextensions
  set /a dec_=%1
  if %dec_% LSS 0 (endlocal & set %2=Error: negative & goto :EOF)
  set bin_=
  :_binloop
    set /a dec1_=%dec_%
    set /a dec_=%dec_% / 2
    set /a bindigit_=%dec1_% - 2*%dec_%
    set bin_=%bindigit_%%bin_%
    if %dec_% GTR 0 goto :_binloop
  endlocal & set %2=%bin_% & goto :EOF
  ::
  ::===============================================================
  :DecimalToOctal DecimalIn OctalOut
  ::
  setlocal enableextensions
  set /a dec_=%1
  if %dec_% LSS 0 (endlocal & set %2=Error: negative & goto :EOF)
  set oct_=
  :_octloop
    set /a dec1_=%dec_%
    set /a dec_=%dec_% / 8
    set /a octdigit_=%dec1_% - 8*%dec_%
    set oct_=%octdigit_%%oct_%
    if %dec_% GTR 0 goto :_octloop
  endlocal & set %2=%oct_% & goto :EOF
  ::
  ::===============================================================
  :DecimalToHex DecimalIn HexOut
  ::
  setlocal enableextensions
  set /a dec_=%1
  if %dec_% LSS 0 (endlocal & set %2=Error: negative & goto :EOF)
  set hex_=
  :_hexloop
    set /a dec1_=%dec_%
    set /a dec_=%dec_% / 16
    set /a hexdigit_=%dec1_% - 16*%dec_%
    set /a hexidx_=%hexdigit_%+1
    for /f "tokens=%hexidx_%" %%h in (
      'echo 0 1 2 3 4 5 6 7 8 9 A B C D E F') do set hexdigit_=%%h
    set hex_=%hexdigit_%%hex_%
    if %dec_% GTR 0 goto :_hexloop
  endlocal & set %2=%hex_% & goto :EOF

The output will be
  D:\TEST>cmdfaq
  Decimal 78 = Binary 1001110
  Decimal 78 = Octal 116
  Decimal 78 = Hexadecimal 4E
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:33 2011
Subject: 33) How can I convert a binary, octal, hexadecimal into a decimal?
Date: Mon, 31 Jan 2011 01:00:33
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  set bin_=1001110
  call :BinToDecimal %bin_% decimal_
  echo Binary %bin_% = decimal %decimal_%
  ::
  set oct_=116
  call :OctToDecimal %oct_% decimal_
  echo Octal %oct_% = decimal %decimal_%
  ::
  set hex_=4E
  call :HexToDecimal %hex_% decimal_
  echo Hexadecimal %hex_% = decimal %decimal_%
  endlocal & goto :EOF
  ::
  ::===============================================================
  :BinToDecimal BinaryIn DecimalOut
  ::
  setlocal enableextensions
  set bin_=%1
  set /a dec_=0
  :_loop
    set first_=%bin_:~0,1%
    set /a dec_=%first_%+2*%dec_%
    set bin_=%bin_:~1%
    if defined bin_ goto _loop
  endlocal & set %2=%dec_% & goto :EOF
  ::
  ::===============================================================
  :OctToDecimal OctIn DecimalOut
  ::
  setlocal enableextensions
  set /a oct_=0%1
  endlocal & set %2=%oct_% & goto :EOF
  ::
  ::===============================================================
  :HexToDecimal HexIn DecimalOut
  ::
  setlocal enableextensions
  set /a hex_=0x%1
  endlocal & set %2=%hex_% & goto :EOF

The output will be
  D:\TEST>cmdfaq
  Binary 1001110 = decimal 78
  Octal 116 = decimal 78
  Hexadecimal 4E = decimal 78

A true application which I needed:
  @echo off & setlocal enableextensions
  ::
  :: Requires a parameter (in hexadecimal)
  if [%1]==[] goto _usage
  ::
  :: Put the parameter into a regular environment variable
  set hex_=%1
  ::
  :: The require format of the parameter is #C1C2C2
  :: Where C1 is the first color in hexadecomal and so on
  set h0_=%hex_:~0,1%
  if not [%h0_%]==[#] goto _usage
  ::
  :: Check that the parameter is not too long
  set h4_=%hex_:~7,1%
  if defined h4_ goto _usage
  ::
  :: Decompose the parameter into three parts with two characters each
  set h1_=%hex_:~1,2%
  set h2_=%hex_:~3,2%
  set h3_=%hex_:~5,2%
  ::
  :: Convert the hexadecimals
  set /a d1_=0x%h1_%
  set /a d2_=0x%h2_%
  set /a d3_=0x%h3_%
  ::
  :: Display the results
  echo %h1_% %h2_% %h3_%
  echo %d1_% %d2_% %d3_%
  goto :EOF
  ::
  :_usage
  echo +----------------------------------------------------+
  echo ^| Covert a hexadecimal color code into decimal       ^|
  echo ^| By Prof. Timo Salmi, Last modified Fri 29-Apr-2005 ^|
  echo +----------------------------------------------------+
  echo.
  echo Usage %~f0 #C1C2C3
  echo.
  echo Where C1 is the first color in hexadecimal and so on
  goto :EOF
The output might be
  C:\_D\TEST>cmdfaq #ff1faa
  ff 1f aa
  255 31 170

If one wants a better error handling, substitute
  ::
  :: Convert the hexadecimals, check the hex input for validity
  set /a d1_=0x%h1_% || (
    echo. & echo Invalid hexadecimal %h1_% in %hex_% & goto :EOF)
  set /a d2_=0x%h2_% || (
    echo. & echo Invalid hexadecimal %h2_% in %hex_%
    goto :EOF)
  set /a d3_=0x%h3_% || (
    echo.
    echo Invalid hexadecimal %h3_% in %hex_%
    goto :EOF)
Note at the same time the demonstrations of different formats. For
more on the conditional processing symbol || see
 hh ntcmds.chm::/ntcmds_shelloverview.htm

References/Comments:
 http://www.google.com/groups?selm=42722b29%240%248298%245a62ac22%40per-qv1-newsreader-01.iinet.net.au
 http://www.google.com/groups?selm=42732693%240%2483065%24ed2619ec%40ptn-nntp-reader01.plus.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:34 2011
Subject: 34) How can I remove the quote characters from a line?
Date: Mon, 31 Jan 2011 01:00:34
From: ts@uwasa.fi (Timo Salmi)

Below is a demonstration
  @echo off & setlocal enableextensions
  ::
  :: Set up a test
  set line_="54321","1","3","1234567890122","","","","","",""
  echo %line_%
  ::
  :: Omit the quotes
  set line_=%line_:"=%
  ::
  :: List the first four fields
  for /f "tokens=1-4 delims=," %%f in ('echo %line_%') do (
    call :ListThem %%f %%g %%h %%i)
  endlocal & goto :EOF
  :: ======================================================
  :ListThem
  setlocal enableextensions
    echo.%1
    echo.%2
    echo.%3
    echo.%4
  endlocal & goto :EOF

The output will be
  D:\TEST>batfaq
  "54321","1","1","1234567890122","","","","","",""
  54321
  1
  3
  1234567890122

Using SED
  @echo off & setlocal enableextensions
  ::
  :: Set up a test
  set line_="54321","1","3","1234567890122","","","","","",""
  echo %line_%
  echo %line_%|sed -e "s/\x22//g"
  for /f "tokens=* delims=" %%a in (
    'echo %line_%^|sed -e "s/\x22//g"') do set lineNQ=%%a
  echo %lineNQ%
  endlocal & goto :EOF

The output is
  C:\_D\TEST>cmdfaq
  "54321","1","3","1234567890122","","","","","",""
  54321,1,3,1234567890122,,,,,,
  54321 1 3 1234567890122
  1) Note the different outcomes. In FOR /F the commas (,) count as default delimiters.
  2) \x22 is hex for "

A Visual Basic Script (VBScript) aided solution (tolerating poison characters):
@echo off & setlocal enableextensions
  rem C:\_M\TEST\CMDTEST.CMD
  ::
  :: Set up a test
  set line_="54321","1","3","1234567890122","","","","","",""
  echo %line_%
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  for /f "tokens=* delims=" %%a in ('
    echo %line_%^|cscript //nologo "%vbs_%"') do (
    set lineNQ=%%a)
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Display the result
  echo %lineNQ%
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    str = Replace (str, Chr(34),"") 'VBS
    WScript.StdOut.WriteLine str 'VBS
  Loop 'VBS

The output
  C:\_M\TEST>cmdtest
  "54321","1","3","1234567890122","","","","","",""
  54321 1 3 1234567890122
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:35 2011
Subject: 35) How can I substitute the second field on each line of my file?
Date: Mon, 31 Jan 2011 01:00:35
From: ts@uwasa.fi (Timo Salmi)

Below is a simple demonstration substituting the second field with
"ab" on all the lines. Note the formulation of the for tokens, so
that all the fields will be covered.

  @echo off
  echo "123","45","678","901","234"> myfile.txt
  echo "234","56","789","012","345">>myfile.txt

  @echo off & setlocal enableextensions
  for /f "tokens=1,3,* delims=," %%q in ('type myfile.txt') do (
    echo %%q,"ab",%%r,%%s>>outfile.txt)
  type outfile.txt
  endlocal & goto :EOF

The output will be
  F:\CMD>d:cmdfaq
  "123","ab","678","901","234"
  "234","ab","789","012","345"

Note that the method will work even if the format of the lines were
"123" , "45" , "678" , "901" ,  "234"
For removing the quotes (if need be) and extracting separately the
contents of each field, see the previous item.

The original task can also be solved with a Visual Basic Script
(VBScript) aided command line script. It is much more complicated and
thus perhaps not practical. However, the code is instructive and
allows for flexibility.

  @echo off & setlocal enableextensions
  ::
  :: Build a test file
  set testfile_=C:\_M\testfile.txt
  > "%testfile_%" echo "123","45","678","901","234"
  >>"%testfile_%" echo "999"
  >>"%testfile_%" echo "888","777"
  >>"%testfile_%" echo.
  >>"%testfile_%" echo "234","56","789","012","345"
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  <"%testfile_%" cscript //nologo "%vbs_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%" "%testfile_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  TargetCol = 2 'VBS
  TargetCol = TargetCol - 1 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    LineStr = WScript.StdIn.ReadLine 'VBS
    LineArray = Split(LineStr, ",", -1, vbTextCompare) 'VBS
    LastI = UBound(LineArray) 'VBS
    For i = 0 to LastI-1 'VBS
      If i = TargetCol Then 'VBS
        WScript.StdOut.Write Chr(34) + "ab" + Chr(34) 'VBS
        If LastI > TargetCol Then WScript.StdOut.Write "," 'VBS
      Else 'VBS
        WScript.StdOut.Write LineArray(i) + "," 'VBS
      End If 'VBS
    Next 'VBS
    If LastI > -1 Then 'VBS
      If LastI = TargetCol Then 'VBS
        WScript.StdOut.WriteLine Chr(34) + "ab" + Chr(34) 'VBS
      Else 'VBS
        WScript.StdOut.WriteLine LineArray(LastI) 'VBS
      End If 'VBS
    Else 'VBS
      WScript.StdOut.WriteLine 'VBS
    End If 'VBS
  Loop 'VBS

The output will be
  F:\CMD>d:cmdfaq
  "123","ab","678","901","234"
  "999"
  "888","ab"

  "234","ab","789","012","345"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:36 2011
Subject: 36) I start a program from my script and it hogs my command window.
Date: Mon, 31 Jan 2011 01:00:36
From: ts@uwasa.fi (Timo Salmi)

A question frequently presented also in a format like "How to start
windows program from batch file without the command prompt window".

Occasionally one may want to call a program from the command line
window. Furthermore, it sometimes is useful to build calling that
program into a script e.g. for customization. However, when one
does, the command window will "freeze" to wait for the completion of
the task. How can one avoid that and free the command window for
other parallel usages? The trick is to start the program using the
START internal command.

The basic format of the start command is
  START "title" command/program
Including the "title" is essential. Most questions and confusion arise
from failing to include it, even if commonly it is left empty:
  START "" whatever

For example, my favorite text editor is the SemWare Editor
Professional. Below is one of the options of how I may call it. It
is a batch/script that is meant to work on both a 95 and on a XP PC.
This means that in Windows95 it must not have to encounter unknown
(CMD.EXE) lines of the batch/script. Furhermore, note the difference
in the format of calling the program with the START.

  @echo off
  :: E.BAT by Prof. Timo Salmi
  :: One option for calling the SemWare Editor Professional
  ::
  if [%OS%]==[Windows_NT] goto _nt
  if [%1]==[] L:\TSEPro\e32 *.*
  if not [%1]==[] L:\TSEPro\e32 %1 %2 %3 %4 %5 %6 %7
  goto _out
  ::
  :_nt
  if "%~1"=="" (
    start "" "C:\Program Files\TSEPro\e32" *.*
      ) else (
    start "" "C:\Program Files\TSEPro\e32" %*)
  ::
  :_out

In the above "the %* batch parameter is a wildcard reference to all
the arguments, not including %0, that are passed to the batch file."

References/Comments:
 http://www.google.com/groups?selm=Xns941E40ABE99FBz9zzaQ2btw%40216.77.188.16
 http://www.google.com/groups?selm=vua9ifpaqeqi92%40corp.supernews.com
 http://www.google.com/groups?selm=rf8jprwem3va.1jkl9tq5cj629%24.dlg%4040tude.net
 http://www.google.com/groups?selm=V0j%l.185$Jb1.130%40flpi144.ffdc.sbc.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:37 2011
Subject: 37) How can I insert a line in the middle of a file with a script?
Date: Mon, 31 Jan 2011 01:00:37
From: ts@uwasa.fi (Timo Salmi)

The logic of the task is simple. Get the first n lines, append your
line, and then get the rest of the lines starting from n+1. The
current task is easy with the additional tools SED or GAWK. Say that
you wish to insert something between the fourth and the fifth line of
your file. Below is how to do it:

  @echo off
  sed -n 1,4p myfile.txt>newfile.txt
  echo Insert My added own line>>newfile.txt
  sed -n 5,$p myfile.txt>>newfile.txt

With G(nu)AWK the solution is even simpler
  gawk '{print;if(NR==4)print"My own added line"}' myfile.txt>newfile.txt

However, this can also be solved with pure script. The solution
below using subroutines is not the most concise one, but hopefully
it is instructive. In a FAQ like this clarity is preferred over
conciseness and sometimes even efficiency. Also note how as a
sideline it answers the questions "How do I get the first N lines of
my text file?" and "How do I get my text file's lines after line N".
(The latter could be answered with "skip=" as well.)

  @echo off & setlocal enableextensions
  :: Make a test file
  for %%f in (myfile.txt mynew.txt) do if exist %%f del %%f
  for %%f in (1 2 3 4 5 6 7 8 9) do echo This is line %%f>>myfile.txt
  ::
  :: Insert where
  set insertAfter=4
  ::
  :: Initialize the linecount
  set /a lineCount=0
  ::
  :: Write the lines until and including the insertion point
  for /f "delims=" %%r in ('type myfile.txt') do (
    call :WriteUntilLine %%r>>mynew.txt
    )
  ::
  :: Insert new text
  echo My added text>>mynew.txt
  ::
  :: Start a new count
  set /a lineCount=0
  ::
  :: Write the lines until and including the insertion point
  for /f "delims=" %%r in ('type myfile.txt') do (
    call :WriteSinceLine %%r>>mynew.txt
    )
  ::
  :: Display the new file
  type mynew.txt
  ::
  :: Clean up
  for %%f in (myfile.txt mynew.txt) do if exist %%f del %%f
  endlocal & goto :EOF

  :: ======================================================
  :WriteUntilLine
  set /a lineCount+=1
  if %lineCount% LEQ %insertAfter% echo %*
  goto :EOF

  :: ======================================================
  :WriteSinceLine
  set /a lineCount+=1
  if %lineCount% GTR %insertAfter% echo %*
  goto :EOF

The output
  D:\TEST>cmdfaq
  This is line 1
  This is line 2
  This is line 3
  This is line 4
  My own added line
  This is line 5
  This is line 6
  This is line 7
  This is line 8
  This is line 9

For a more concise, and also instructive alternative see
http://www.google.com/groups?selm=brrnkc%246ou2e%241%40ID-55492.news.uni-berlin.de

For replacing a line instead of inserting, substitute
  if %lineCount% LEQ %insertAfter% echo %*
with
  if %lineCount% LSS %insertAfter% echo %*

Note the standard feature (or limitation, if you will) of the pure
script solution: If there are empty lines they will be omitted.

A Visual Basic Script (VBScript) aided command line script can be
used. It does not ignore the potential empty lines.
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\slice.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Do the inserting
  cscript //nologo "%vbs_%" 1 3 < "My test file.txt"
  echo Inserted text after line 3!
  cscript //nologo "%vbs_%" 4 99999 < "My test file.txt"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'The Visual Basic Script for "slice"
  '
  StartFromLineNumber=WScript.Arguments.Unnamed(0) 'VBS
  EndAtLineNumber=WScript.Arguments.Unnamed(1) 'VBS
  i = 0 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    i = i + 1 'VBS
    If (i >= CLng(StartFromLineNumber)) And (i <= CLng(EndAtLineNumber)) Then 'VBS
      WScript.StdOut.WriteLine str 'VBS
    End If 'VBS
  Loop 'VBS

Assume the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

The output will be
C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  Inserted text after line 3!
  line 4 ""

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

You might wish to see also the later item #69 "How do I get the first,
or the last, 400 lines of a file?".
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:38 2011
Subject: 38) How can I set and test the errorlevel within a script file?
Date: Mon, 31 Jan 2011 01:00:38
From: ts@uwasa.fi (Timo Salmi)

Many programs return an errorlevel, which then can be tested for. One
of such programs is the familiar C:\WINDOWS\system32\find.exe. For
example one could have
  @echo off & setlocal enableextensions
  set var_=Testing
  echo %var_%|find "a">nul
  set el_=%ERRORLEVEL%
  echo el_=%el_%
  endlocal & goto :EOF
The output would be
  C:\_D\TEST>cmdfaq
  el_=1
For one of the applications see Item #42.

EXIT can be used to set the errorlevel. Note the ^2 to avoid it from
being mistaken for a handle.
  @echo off & setlocal enableextensions
  echo.@exit /B ^2>tmp$$$.cmd
  call tmp$$$
  for %%e in (0 1 2 3 4 5 6 7 8 9) do (
    if %errorlevel% EQU %%e echo The errorlevel is %%e)
  echo Bye from %0 on %date% at %time%
  for %%f in (tmp$$$.cmd) do if exist %%f del %%f
  goto :EOF
The output will be something like
  D:\TEST>cmdfaq
  The errorlevel is 2
  By from cmdfaq on 19.12.2003 at  8:18:03.21

Another alternative is to utilise gawk:
  @echo off & setlocal enableextensions
  :: Requires G(nu)AWK
  gawk 'BEGIN{exit 2}'
  for %%e in (0 1 2 3 4 5 6 7 8 9) do (
    if %errorlevel% EQU %%e echo The errorlevel is %%e)
  echo Bye from %0 on %date% at %time%
  goto :EOF
The output will be something like
  F:\CMD>d:\test\cmdfaq
  The errorlevel is 2
  By from d:\test\cmdfaq on 19.12.2003 at  8:19:08.69

A wider scale for testing the errorlevel. Note that the errorlevel
must be stored before the next SET because also SET sets the
errorlevel.
  @echo off & setlocal enableextensions enabledelayedexpansion
  echo.@exit /B ^5>"%temp%\tmp$$$.cmd"
  call "%temp%\tmp$$$"
  set errorlev_=%errorlevel%
  set /a e_=0
  :_loop
    if !errorlev_! EQU %e_% (
      echo The errorlevel is %e_%
      ) else (
      set /a e_+=1
      if %e_% LEQ 255 goto _loop)
  for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
  goto :EOF

With Visual Basic Script one can have
  @echo off & setlocal enableextensions
  :: Make a temporary folder
  if not exist c:\mytemp mkdir c:\mytemp
  ::
  :: Set the errorlevel
  echo WScript.Quit ^5>c:\mytemp\tmp$$$.vbs
  cscript //nologo c:\mytemp\tmp$$$.vbs
  ::
  for %%e in (0 1 2 3 4 5 6 7 8 9) do (
    if %errorlevel% EQU %%e echo The errorlevel is %%e)
  ::
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.vbs) do del %%f
  rmdir c:\mytemp
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  The errorlevel is 5

Or, written alternatively
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\slice.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: A call returning an errorlevel
  cscript //nologo "%vbs_%"
  ::
  for %%e in (0 1 2 3 4 5 6 7 8 9) do (
    if %errorlevel% EQU %%e echo The errorlevel is %%e)
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'A Visual Basic Script returning an errorlevel
  WScript.Quit 5 'VBS

Actually, an XP srcipt can return an errorlevel without any
additional tricks as demonstrated below
  @echo off & setlocal enableextensions
  set cmdfile_="temp $$$.cmd"
  echo @exit /b ^2>%cmdfile_%
  call %cmdfile_%
  for %%e in (0 1 2 3 4 5 6 7 8 9) do (
    if %errorlevel% EQU %%e echo The errorlevel is %%e)
  for %%f in (%cmdfile_%) do if exist %%f del %%f
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  The errorlevel is 2

 Q: Is there any reason why echo The errorlevel is %errorlevel% wouldn't
accomplish the same, even showing errorlevels above 9?

Of course, if the echoing is all that is wished for. But that is not
the essence here. The point is that one may wish to cover a certain
range or levels, and one may wish to take action depending one the
level. That is why the more involved formulation. But, indeed one can
simply write
  whateverCommand
  echo %%errorlevel%%=%errorlevel%

One important consideration in testing an errorlevel is to do it
immediately after a command, that is without any other intervening
commands that might affect the errorlevel results.

Furthermore, there are some common mistakes that are made with the
errorlevels. From the days of MS-DOS the following, now optional
format is familiar to some of the readers
  if ERRORLEVEL number DoWhatever
The above specifies a true condition only if the previous program run
by CMD.EXE returned an exit code equal to or greater than number. That
is easily misunderstood or forgotten. For example, consider
  @echo off & setlocal enableextensions
  dir /a:d C:\|findstr /c:"No such folder"
  echo %%errorlevel%%=%errorlevel%
  if errorlevel 0 echo The errorlevel is 0
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  %errorlevel%=1
  The errorlevel is 0
That happens because ERRORLEVEL 0 always is true.

In the XP scripting its is more clear to write
  @echo off & setlocal enableextensions
  dir /a:d C:\|findstr /c:"No such folder"
  echo %%errorlevel%%=%errorlevel%
  if %errorlevel% EQU 0 echo The errorlevel is 0
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  %errorlevel%=1

Another potential source of confusion is setting the errorlevel
directly with set. It is not advisable to do that. For example
  @echo off & setlocal enableextensions
  set errorlevel=0
  dir /a:d C:\|findstr /c:"No such folder"
  echo %%errorlevel%%=%errorlevel%
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  %errorlevel%=0

Yet another common mistake involves misunderstading or ignoring
delayed variable expansion (the principle is not limited to
errorlevels, but is typical in for and if constructs). Consider
  @echo off
  setlocal enableextensions enabledelayedexpansion
  set cmdfile_=%temp%\tmpcmd.cmd
  echo @exit /b ^2>"%cmdfile_%"
  if "%OS%"=="Windows_NT" (
    call "%cmdfile_%"
    echo errorlevel=%errorlevel%)
  if "%OS%"=="Windows_NT" (
    call "%cmdfile_%"
    echo errorlevel=!errorlevel!)
  for %%f in ("%cmdfile_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  errorlevel=0
  errorlevel=2
Where only the latter is correct.

If for some reason you wish to use the old DOS errorlevel cumbersome
errorlevel testing syntax, the following demonstration might be of
help.
  @echo off & setlocal enableextensions
  set cmdfile_=%temp%\tmpcmd.cmd
  ::
  echo @exit /b ^2>"%cmdfile_%"
  ::
  echo.
  call "%cmdfile_%"
  if errorlevel 3 if not errorlevel 4 echo The errorlevel is exactly 3
  if errorlevel 2 if not errorlevel 3 echo The errorlevel is exactly 2
  if errorlevel 1 if not errorlevel 2 echo The errorlevel is exactly 1
  if errorlevel 0 if not errorlevel 1 echo The errorlevel is exactly 0
  echo.
  ::
  call "%cmdfile_%"
  if errorlevel 3 echo The errorlevel is at least 3
  if errorlevel 2 echo The errorlevel is at least 2
  if errorlevel 1 echo The errorlevel is at least 1
  if errorlevel 0 echo The errorlevel is at least 0
  ::
  for %%f in ("%cmdfile_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq

  The errorlevel is exactly 2

  The errorlevel is at least 2
  The errorlevel is at least 1
  The errorlevel is at least 0

References/Comments:
 http://www.google.com/groups?selm=bs4nl5%249co%2404%241%40news.t-online.com
 http://www.google.com/groups?selm=486CE4CA.1D3C0EB5%40unibwm.de
 http://www.google.com/groups?selm=486dcacb%240%2423826%24a82e2bb9%40reader.athenanews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:39 2011
Subject: 39) Is there a subroutine to convert a variable into uppercase?
Date: Mon, 31 Jan 2011 01:00:39
From: ts@uwasa.fi (Timo Salmi)

As below. Note that the substitution method is case insensitive,
which means that while working for this application, it is not
useful for all character substitution tasks. Also note the minor
detail of the Scandinavian character conversion.

  @echo off & setlocal enableextensions
  set myvar_=My Test String!  
  echo %myvar_%
  call :ToUpcase "%myvar_%" myvar_
  echo %myvar_%
  endlocal & goto :EOF
  ::
  :: ======================
  :ToUpcase
  setlocal enableextensions
  set var_=%1
  set var_=%var_:a=A%
  set var_=%var_:b=B%
  set var_=%var_:c=C%
  set var_=%var_:d=D%
  set var_=%var_:e=E%
  set var_=%var_:f=F%
  set var_=%var_:g=G%
  set var_=%var_:h=H%
  set var_=%var_:i=I%
  set var_=%var_:j=J%
  set var_=%var_:k=K%
  set var_=%var_:l=L%
  set var_=%var_:m=M%
  set var_=%var_:n=N%
  set var_=%var_:o=O%
  set var_=%var_:p=P%
  set var_=%var_:q=Q%
  set var_=%var_:r=R%
  set var_=%var_:s=S%
  set var_=%var_:t=T%
  set var_=%var_:u=U%
  set var_=%var_:v=V%
  set var_=%var_:w=W%
  set var_=%var_:x=X%
  set var_=%var_:y=Y%
  set var_=%var_:z=Z%
  set var_=%var_:=%
  set var_=%var_:=%
  set var_=%var_:=%
  set var_=%var_:"=%
  endlocal & set %2=%var_%& goto :EOF

The output is
  C:\_D\TEST>cmdfaq
  My Test String!  
  MY TEST STRING!  

More concisely, one can capitalize (if you pardon the pun) on the
fact that in for and the substitution lower and upper case source
are equivalent.
  @echo off & setlocal enableextensions enabledelayedexpansion
  set myvar_=My Test String  
  echo %myvar_%
  call :ToUpcase "%myvar_%" myvar_
  echo %myvar_%
  endlocal & goto :EOF
  ::
  :: ======================
  :ToUpcase
  setlocal enableextensions
  set var_=%~1
  for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z   ) do (
    set var_=!var_:%%c=%%c!
    )
  endlocal & set %2=%var_%& goto :EOF
The output is
  C:\_D\TEST>cmdfaq
  My Test String!  
  MY TEST STRING  

Another option is
  @echo off & setlocal enableextensions
  set myvar_=My Test String!  
  echo %myvar_%
  call :ToUpcaseWithGawk "%myvar_%" myvar_
  echo %myvar_%
  endlocal & goto :EOF
  ::
  :: ================================================================
  :ToUpcaseWithGawk
  :: Requires G(nu)AWK
  setlocal enableextensions
  gawk 'BEGIN{printf"@set var_=%%s\n",toupper(%1)}'>"%temp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  endlocal & set %2=%var_% & goto :EOF

The output again is slightly different
  C:\_D\TEST>cmdfaq
  My Test String!  
  MY TEST STRING!  

Another script-only method. More complicated, but on the side
demonstrates several features of cmd script programming.
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Constants for the lower and upper case
  set dn=abcdefghijklmnopqrstuvwxyz
  set up=ABCDEFGHIJKLMNOPQRSTUVWXYZ
  ::
  :: Set a test string
  if "%~1"=="" (
    set Str=This is a test string
    ) else (
    set Str=%*
    )
  ::
  :: Get the length of the string assuming a max of 255
  set charCount=0
  for /l %%i in (0,1,254) do (
    set char=!Str:~%%i,1!
    if defined char set /a charCount+=1)
  ::
  :: Upcase character by character
  set StrUp=
  for /l %%i in (0,1,%charCount%) do (
    set char=!Str:~%%i,1!
    for /l %%p in (0,1,28) do (
      if [!char!]==[!dn:~%%p^,1!] set char=!up:~%%p,1!
      )
    set StrUp=!StrUp!!char!
    )
  ::
  :: Display the result
  echo %Str%
  echo %StrUp%
  endlocal & goto :EOF
An example of the output
  C:\_D\TEST>cmdfaq  Hello  World!  
  Hello  World  
  HELLO  WORLD  

There are other options. Using SED we can have
  @echo off & setlocal enableextensions
  set myvar_=My Test String!  
  echo %myvar_%
  call :ToUpcaseWithSed "%myvar_%" myvar_
  echo %myvar_%
  endlocal & goto :EOF
  ::
  :: ====================================================================
  :ToUpcaseWithSed
  :: Requires SED
  setlocal enableextensions
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  echo @set var_=%1^
    |sed "y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/"^
    |sed -e "s/\"//g">%temp_%\tmp$$$.cmd
  for %%c in (call del) do %%c %temp_%\tmp$$$.cmd
  endlocal & set %2=%var_% & goto :EOF

The output is
  C:\_D\TEST>cmdfaq
  My Test String!  
  MY TEST STRING!  

The conversion can also be done with a Visual Basic Script
(VBScript) aided command line script
  @echo off & setlocal enableextensions
  ::
  :: The text to be concerved to upper case
  set MyText_=Scripts are fun, or are they?
  ::
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp%\tmp$$$.vbs"
  :: Call the command line script wchich the script host built
  call "tmp$$$.cmd"
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs"
              "tmp$$$.cmd") do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo %MyText_%
  echo %MyTextUp_%
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Dim MyString, MyStringUp                                                'VBS
  Set WshShell = WScript.CreateObject("WScript.shell")                    'VBS
  MyString=WshShell.ExpandEnvironmentStrings("%MyText_%")                 'VBS
  MyStringUp = UCase(MyString)                                            'VBS
  WshShell.run "cmd /c echo @set MyTextUp_=" & MyStringUp & ">tmp$$$.cmd" 'VBS

or, more concisely
  @echo off & setlocal enableextensions
  ::
  :: The text to be concerved to upper case
  set MyText_=Scripts are fun, or are they?
  ::
  :: Utilize a Visual Basic Script
  echo Wscript.Echo UCase^("%MyText_%"^)>"%temp%\tmp$$$.vbs"
  type "%temp%\tmp$$$.vbs"
  for /f "tokens=* delims=" %%s in (
    'cscript //nologo "%temp%\tmp$$$.vbs"') do set MyTextUp_=%%s
  ::
  :: Demonstrate the result
  echo %MyText_%
  echo %MyTextUp_%
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=bs12o7%248fgvr%241%40ID-55492.news.uni-berlin.de
 http://www.google.com/groups?selm=bs2ald%248oc84%241%40ID-55492.news.uni-berlin.de
Also see ftp://garbo.uwasa.fi/pc/link/tsbat.zip item #7
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:40 2011
Subject: 40) How do I get the number of arguments given to a script?
Date: Mon, 31 Jan 2011 01:00:40
From: ts@uwasa.fi (Timo Salmi)

This task is not quite as trivial as it first appears to be. There
are a couple of subtle pitfalls. Since the solution uses shift it
"destroys" the parameters from later usage, so they have to be
stored. The logic is that if one wants to count the parameters, one
is likely also to want to use the parameters! Also note the usage of
[] in the if testing lest there is confusion with parameters
potentially enclosed in quotes. If one needs a parameter count, it
is logical and sensible to always put it as the first thing into the
script. The denotations in the example below have clear UNIX
connotations.

Take one:
========

  @echo off & setlocal enableextensions enabledelayedexpansion
  set /a argc=0
  :_argcLoop
    if [%1]==[] goto _exitargcLoop
    set /a argc+=1
    set arg%argc%=%1
    shift
    goto _argcLoop
  :_exitargcLoop
  ::
  :: Show the results
  echo The number of parameters is %argc%
  set /a count_=0
  :_dispLoop
    set /a count_+=1
    if defined arg%count_% (echo !arg%count_%! & goto _dispLoop)
  ::
  endlocal & goto :EOF

An example:
  D:\TEST>cmdfaq one two "the third"
  The number of parameters is 3
  one
  two
  "the third"

If you wish to omit the quotes (") substitute
  set arg%argc%=%~1

Take two:
========

  @echo off & setlocal enableextensions enabledelayedexpansion
  set argc=0
  :_loop
    if "%~1"=="" goto _next
    set /a argc+=1
    set argv[!argc!]=%~1
    shift
    goto _loop
  :_next
  ::
  echo argc=%argc%
  for /l %%i in (1,1,%argc%) do echo argv[%%i]=!argv[%%i]!
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq a  b c "d e"
  argc=4
  argv[1]=a
  argv[2]=b
  argv[3]=c
  argv[4]=d e

Note a catch. After you apply the above, you no longer can access
the original parameters. If you need them later in the batch, you
have to store them at the outset of the batch file like in the above.

Let's consider a more complicated extraction of command line
information:
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: The task:
  :: Get switches and ordinary parameters given to a script.
  :: Distinguish between the two categories
  ::
  set argc=0
  :_loop
    if "%~1"=="" goto _next
    set /a argc+=1
    set argv[!argc!]=%~1
    shift
    goto _loop
  :_next
  ::
  echo argc=%argc%
  for /l %%i in (1,1,%argc%) do echo argv[%%i]=!argv[%%i]!
  ::
  set paramCount=0
  set switchCount=0
  for /l %%i in (1,1,%argc%) do (
    echo.!argv[%%i]!| find "/">nul
    if !errorlevel! EQU 0 (
      set /a switchCount+=1
      set switch[!switchCount!]=!argv[%%i]!
      ) else (
      set /a paramCount+=1
      set param[!paramCount!]=!argv[%%i]!
      )
    )
  ::
  echo switchCount=%switchCount%
  echo paramCount=%paramCount%
  for /l %%i in (1,1,%switchCount%) do (
    echo swithch[%%i]=!switch[%%i]!)
  for /l %%i in (1,1,%paramCount%) do (
    echo param[%%i]=!param[%%i]!)
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq a /b /c "Hello World" /?
  argc=5
  argv[1]=a
  argv[2]=/b
  argv[3]=/c
  argv[4]=Hello World
  argv[5]=/?
  switchCount=3
  paramCount=2
  swithch[1]=/b
  swithch[2]=/c
  swithch[3]=/?
  param[1]=a
  param[2]=Hello World

Take three:
==========

Let's drop the switch handing but add how to get the parameters so
that also the poison characters can be handled. At the same time the
code is much streamlined. Note the trick to use the call. Also, no
shift.

  @echo off & setlocal enableextensions disabledelayedexpansion
  set n=0
  for %%a in (%*) do (set /a n+=1)&(call set p[%%n%%]=%%a)
  ::
  echo n=%n%
  for /L %%i in (1,1,9) do if defined p[%%i] call echo p[%%i]=%%p[%%i]%%
  for /L %%i in (2,1,9) do if defined p[%%i] call set rest_=%%rest_%% %%p[%%i]%%
  if defined rest_ set rest_=%rest_:~1%
  echo rest_=%rest_%
  endlocal & goto :EOF

An example of the output
  C:\_D\TEST>cmdfaq 1 2 3 "Hello World" "a & b"
  n=5
  p[1]=1
  p[2]=2
  p[3]=3
  p[4]="Hello World"
  p[5]="a & b"
  rest_=2 3 "Hello World" "a & b"

Take four:
=========

A Visual Basic Script (VBScript) aided command line script giving the
number of parameters
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  > "%vbs_%" echo Set argv = WScript.Arguments
  >>"%vbs_%" echo WScript.Echo argv.count
  for /f %%a in ('cscript //nologo "%vbs_%" %*') do (
    set argc=%%a)
  for %%f in ("%vbs_%") do if exist %%f del %%f
  echo argc=%argc%
  endlocal & goto :EOF

An example of the output
  C:\_D\TEST>cmdfaq 1 2 3 "Hello World" "a & b"
  argc=5

Let's also get the value of the last parameter
  @echo off & setlocal enableextensions
  set vbs_=%temp%\tmp$$$.vbs
  > "%vbs_%" echo Set argv = WScript.Arguments
  >>"%vbs_%" echo If argv.count = 0 Then
  >>"%vbs_%" echo   WScript.Echo argv.count, "None"
  >>"%vbs_%" echo   Else
  >>"%vbs_%" echo   WScript.Echo argv.count, argv(argv.count-1)
  >>"%vbs_%" echo End If
  for /f "tokens=1,*" %%a in ('cscript //nologo "%vbs_%" %*') do (
    set argc=%%a
    set argLast="%%b")
  for %%f in ("%vbs_%") do if exist %%f del %%f
  echo argc=%argc%
  echo argLast=%argLast%
  endlocal & goto :EOF

An example of the output
  C:\_D\TEST>cmdfaq 1 2 3 "Hello World" "a & b"
  argc=5
  argLast="a & b"

References/Comments:
 http://www.google.com/groups?selm=bs6li2%24bth%2404%241%40news.t-online.com
 http://www.google.com/groups?selm=Buvnc.404043%24Pk3.48231%40pd7tw1no
 http://www.google.com/groups?selm=mcg1bqF0MknAFwGV%40merlyn.demon.co.uk
 http://www.google.com/groups?selm=443e85ec%240%247489%249b536df3%40news.fv.fi
 http://www.google.com/groups?selm=nn8ks3d9l8k25c0b742or17cg38k3s8j6u%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:41 2011
Subject: 41) How can I create a zero-byte file? How do I test for it?
Date: Mon, 31 Jan 2011 01:00:41
From: ts@uwasa.fi (Timo Salmi)

  @echo off
  rem Don't destroy an existing file
  if exist testfile goto _nocreate
  :: Create the zero-byte file
  type nul>testfile
  :_nocreate
or
  @echo off
  if exist testfile goto _nocreate    %Don't destroy an existing file%
  echo off>testfile
  :_nocreate

Alternatively
  @echo off
  copy /-y nul testfile

To see one of the small but significant differences bewtween
NT/2000/XP and MS-DOS+Win../95/98/Me solutions compare the above
solution with item #42 of ftp://garbo.uwasa.fi/pc/link/tsbat.zip
In MS-DOS+Win../95/98/Me rem can used for the purpose, but not the
copy nul solution.

Another option. This time with a long name and also a file-size test
included.
  @echo off & setlocal enableextensions
  set testfile_="My test file"
  if exist %testfile_% goto _nocreate    %Don't destroy an existing file%
  copy nul %testfile_%>nul
  :_nocreate
  call :TestForZeroFile %testfile_% isZeroFile_
  echo %testfile_% is a zero-byte file = %isZeroFile_%
  endlocal & goto :EOF
  ::
  :: ====================================
  :TestForZeroFile
  setlocal enableextensions
  set file_=%1
  for %%f in (%file_%) do set size_=%%~zf
  set return_=false
  if %size_% EQU 0 set return_=true
  endlocal & set %2=%return_% & goto :EOF

Screen captures:
  D:\TEST>cmdfaq
  "My test file" is a zero-byte file = true

  D:\TEST>dir | find "My"
  24.12.2003  09:56                 0 My test file

Or, simpler still the test could be codes as
  :: ====================================
  :TestForZeroFile
  setlocal enableextensions
  set size_=%~z1
  set return_=false
  if %size_% EQU 0 set return_=true
  endlocal & set %2=%return_% & goto :EOF

As an unrelated aside, note the three alternatives employed in this
item of making comments, including using the percent % signs.
Actually, the trick is just using non-existing environment variables.

References/Comments:
 http://www.google.com/groups?selm=n1adn1dd8pc6l3hfksq2i8v0vusg3qgrnb%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:42 2011
Subject: 42) What is the subroutine for testing a filename for wildcards?
Date: Mon, 31 Jan 2011 01:00:42
From: ts@uwasa.fi (Timo Salmi)

Based on the comment given in the thread referred to in the "
References/Comments " at the and of this item
  @echo off & setlocal enableextensions
  set filename_="My * file"
  echo %filename_%|findstr "[*?]">nul
  if %errorlevel% EQU 0 (
    echo %filename_% contains wildcards
    ) else (
    echo No wildcards in %filename_%)
  endlocal & goto :EOF

Note that this also could be written as
  @echo off & setlocal enableextensions
  set filename_="My * file"
  echo %filename_%|findstr "[*?]">nul ^
    && echo %filename_% contains wildcards^
    || echo No wildcards in %filename_%
  endlocal & goto :EOF

The output would obviously be
  C:\_D\TEST>cmdfaq
  "My * file" contains wildcards

Another take, written with a subroutine and FIND instead of FINDSTR.
  @echo off & setlocal enableextensions
  ::
  :: Demo
  set filename_=My * file
  call :IsWildSub "%filename_%" isWild
  if "%isWild%"=="yes" (
    echo "%filename_%" contains wildcards
    ) else (
    echo No wildcards in "%filename_%")
  ::
  set filename_=My file
  call :IsWildSub "%filename_%" isWild
  if "%isWild%"=="yes" (
    echo "%filename_%" contains wildcards
    ) else (
    echo No wildcards in "%filename_%")
  endlocal & goto :EOF
  ::
  :: =====================================================
  :: Does a name contain wildcards * and/or ?
  :IsWildSub
  setlocal enableextensions
  echo %1|find "*">nul
  if %errorlevel% EQU 0 (endlocal & set %2=yes& goto :EOF)
  echo %1|find "?">nul
  if %errorlevel% EQU 0 (endlocal & set %2=yes& goto :EOF)
  endlocal & set %2=no& goto :EOF

There is a somewhat unrelated aside to wildcards in MS scripting which
differs from the usage which UNIX users in particular are accustomed
to. Consider a folder containing the following files.
  a.txt
  ab.txt
  abc.txt
  abcd.txt
As expected
  dir /b *.txt
will give
  a.txt
  ab.txt
  abc.txt
  abcd.txt
however,
  dir /b ??.txt
will give
  a.txt
  ab.txt
i.e. the ?? will match both one and two characters. If one wishes to
match exactly two characters, then one has to use something like
  dir /b "C:\_M\??.txt"|findstr /i "..\.txt"
which will give
  ab.txt

What about two or more characters?
  dir /b "C:\_M\*.txt"|findstr /i "..\.txt"
which will give
  ab.txt
  abc.txt
  abcd.txt

References/Comments:
  http://www.google.com/groups?selm=bsfh6p$4kn%40poiju.uwasa.fi
  hh ntcmds.chm::/ntcmds_shelloverview.htm
  http://groups.google.com/group/alt.msdos.batch.nt/msg/f5fcc9d322e33fd5
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:43 2011
Subject: 43) Is there a way of counting the number of files in a folder?
Date: Mon, 31 Jan 2011 01:00:43
From: ts@uwasa.fi (Timo Salmi)

First off, let's exclude the files in the subfolders from the
consideration and take the information directly from the folder listing
  @echo off & setlocal enableextensions
  set folder_=C:\_D\TEST
  for /f "tokens=1" %%f in ('
    dir "%folder_%\*.*"^|findstr /c:" File(s)"') do (
      set countf_=%%f)
  for /f "tokens=1" %%d in ('
    dir "%folder_%\*.*"^|findstr /c:" Dir(s)"') do (
      set countd_=%%d)
  echo %folder_%
  echo Found %countf_% files, %countd_% folders
  endlocal & goto :EOF
The output might be something like
  C:\_D\TEST
  Found 20 files, 2 folders
Note that the above includes the . and .. inherent in every folder-

Next let's include the subfolders and actually count the number of
files and subfolders instead of extracting the information from the
folder summary. (The . and .. are excluded.)
  @echo off & setlocal enableextensions
  set startFolder=C:\_D
  set /a countd_=0
  set /a countf_=0
  for /f %%f in ('dir /s /b /a:d  "%startFolder%\*.*"') do set /a countd_+=1
  for /f %%f in ('dir /s /b /a:-d "%startFolder%\*.*"') do set /a countf_+=1
  echo Found %countf_% files, %countd_% subfolders
  echo in and below "%startFolder%"
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq
  Found 2801 files, 146 subfolders
  in and below "C:\_D"

Let's not stop there, but list the files together with an ordinal
number.
  @echo off & setlocal enableextensions
  set startFolder=C:\_D
  set /a FileCount_=0
  for /f "delims=" %%f in ('
    dir /s /b /a:-d /o:e "%startFolder%\*.*"') do (
      call :ListOneFile "%%f")
  endlocal & goto :EOF
  ::
  :: ===========================================
  :ListOneFile
  set /a FileCount_+=1
  call :FuncRightJustify5 %FileCount_% FileCount_
  echo %FileCount_: =0% %*
  goto :EOF
  ::
  :: ===========================================
  :FuncRightJustify5 arg1 arg2
  setlocal enableextensions
  set number_=    %1
  set number_=%number_:~-5%
  endlocal & set "%2=%number_%" & Goto :EOF

The output might be something like
  C:\_D\TEST>cmdfaq
  00001 "C:\_D\HAE.BAT"
  :
  00017 "C:\_D\BAS\CMDFAQ2.CMD"
  00018 "C:\_D\BAS\FAQPAS.PAS"
  00019 "C:\_D\BAS\koe & 3.txt"
  00020 "C:\_D\BAS\koe (4!).txt"
  00021 "C:\_D\BAS\VBSFAQ.VBS"
  :
  02800 "C:\_D\WORD\WORDVB.TXT"
  02801 "C:\_D\WORD\wordxml.xml"

The problem can also be solved with a VBS-aided script (giving the
same output as in the above)
  @echo off & setlocal enableextensions
  ::
  set topfolder_=C:\_D
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%topfolder_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  ' The Visual Basic Script
  '
  Sub TraverseOneFolder(foldername) 'VBS
    Dim fso, f, f1, fc 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(foldername) 'VBS
    Set fc = f.Files 'VBS
    For Each f1 in fc 'VBS
      i = i + 1 'VBS
      Wscript.Echo PadFn(CStr(i),5), f1 'VBS
    Next 'VBS
  End Sub 'VBS
  '
  Sub TraverseManyFolders(startfoldername) 'VBS
    Dim fso, f, f1, sf 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(startfoldername) 'VBS
    If Instr (1, Ucase(f), "RECYCLER") = 0 Then 'VBS
      TraverseOneFolder(f) 'VBS
    End If 'VBS
    Set sf = f.SubFolders 'VBS
    For Each f1 in sf 'VBS
      If Instr (1, Ucase(f1), "RECYCLER") = 0 Then 'VBS
        TraverseManyFolders(f1) 'VBS
      End If 'VBS
    Next 'VBS
  End Sub 'VBS
  '
  Function PadFn (str, n) 'VBS
    If Len(str) > n Then 'VBS
      PadFn = str 'VBS
    Else 'VBS
      PadFn = Right(String(n-1,"0")&str,n) 'VBS
    End If 'VBS
  End Function 'VBS
  '
  ' The main script
  i = 0 'VBS
  TraverseManyFolders(WScript.Arguments.Unnamed(0)) 'VBS
If you just wish to count the top folder change TraverseManyFolders to
TraverseOneFolder on the last line.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:44 2011
Subject: 44) How do I get the first 68 columns from a text file?
Date: Mon, 31 Jan 2011 01:00:44
From: ts@uwasa.fi (Timo Salmi)

Actually, needed this one for my own tasks.
  @echo off & setlocal enableextensions disabledelayedexpansion
  set filename_=myfile.txt
  if not exist "%filename_%" (
    echo File "%filename_%" not found
    goto :EOF)
  if exist "outfile.txt" del "outfile.txt"
  for /f "delims=" %%r in ('type "%filename_%"') do call :WriteLine68 %%r
  dir "outfile.txt"
  endlocal & goto :EOF
  ::
  :: ============================
  :WriteLine68
  setlocal enableextensions
  set line_=%*
  echo %line_:~0,68%>>"outfile.txt"
  endlocal & goto :EOF

Be aware of the limitations inherent to CMD.EXE. The empty lines will
be deleted, special symbols such as > and single %:s dropped, %%
reduced to %, and so on. Thus, the usefulness depends on the
circumstances of the application. Consequently, a Visual Basic Script (
VBScript) aided command line script solution can be written which does
not have these limitations.

  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Where from and where to
  set infile_=C:\_M\myfile.txt
  set outfile_=C:\_M\outfile.txt
  if not exist "%infile_%" (
    echo File "%infile_%" not found
    goto :EOF)
  if exist "%outfile_%" del "%outfile_%"
  ::
  :: Build a Visual Basic Script
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp_%\tmp$$$.vbs"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp_%\tmp$$$.vbs" "%infile_%" "%outfile_%"
  ::
  :: Clean up
  for %%f in ("%temp_%\tmp$$$.vbs") do del "%%~f"
  ::
  :: Display
  type "%outfile_%"
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim fso, arg, f1, f2, line 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set arg = WScript.Arguments 'VBS
  Set f1 = fso.OpenTextFile(arg(0), ForReading, True) 'VBS
  Set f2 = fso.OpenTextFile(arg(1), ForWriting, True) 'VBS
  Do While Not f1.AtEndOfStream 'VBS
    line = f1.ReadLine 'VBS
    f2.WriteLine Mid(line, 1, 68) 'VBS
  Loop 'VBS
  f2.Close 'VBS

However, by far the easiest solution to write is
  @echo off & setlocal enableextensions
  set filename_=C:\_M\myfile.txt
  if not exist "%filename_%" (
    echo File "%filename_%" not found
    goto :EOF)
  gawk '{printf"%%s\n",strftime(substr($0,1,68))}' "%filename_%"
  endlocal & goto :EOF

References/Comments:
  http://msdn2.microsoft.com/en-us/library/t0aew7h6(VS.85).aspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:45 2011
Subject: 45) How can I find out how many days old a file is?
Date: Mon, 31 Jan 2011 01:00:45
From: ts@uwasa.fi (Timo Salmi)

The accompanying FILEAGE.CMD script has been written for that
purpose. An example of the output

  C:\_F\CMD>echo %date%
  11.04.2008

  C:\_F\CMD>fileage fileage.cmd
  +----------------------------------------------------+
  | FILEAGE.CMD script to find out how old a file is   |
  | By Prof. Timo Salmi, Last modified Sat 22-Dec-2007 |
  +----------------------------------------------------+

  22.12.2007 13:53 2471 C:\_F\CMD\FILEAGE.CMD
  The file is 111 days old

or

  @echo off & setlocal enableextensions
  ::
  :: The target file
  set filename_=%~1
  if not exist "%filename_%" (
    echo File "%filename_%" not found
    goto :EOF)
  ::
  :: Get filedate. Assume a file date format of DD.MM.YYYY HH:MN
  set fdate_=%~t1
  set fdd_=%fdate_:~0,2%
  set fmm_=%fdate_:~3,2%
  set fyyyy_=%fdate_:~6,4%
  ::
  echo %fdd_%.%fmm_%.%fyyyy_% "%filename_%"
  ::
  >"%temp%\tmp$$$.vbs" echo WScript.Echo DateDiff("d", DateValue("%fdd_%, %fmm_%, %fyyyy_%"), Date)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set ago_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  ::
  echo The file is %ago_% days old
  ::
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>date /t
  11.04.2008

  C:\_D\TEST>cmdfaq "CMDFAQ2.CMD"
  07.04.2008 "CMDFAQ2.CMD"
  The file is 4 days old

Or, writing it out here in a locale date-tolerant format
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: The target file
  set filename_=%~1
  if not exist "%filename_%" (
    echo File "%filename_%" not found
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  for /f "tokens=*" %%a in ('
    cscript //nologo "%vbs_%" "%filename_%"') do (
      set ago_=%%a)
  ::
  :: Show the results
  echo "%filename_%" is %ago_% days old
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  ' Get the age of a file in days
  Function FileAgeFn(filename) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFile(filename) 'VBS
    FileAgeFn = DateDiff("d", f.DateLastModified, currentdate) 'VBS
  End Function 'VBS
  '
  ' Display the age of a file
  Sub DisplayFileAge(filename) 'VBS
    WScript.Echo FileAgeFn(filename) 'VBS
  End Sub 'VBS
  '
  ' The VBS main program
  currentdate = Date 'VBS
  set arg = WScript.Arguments 'VBS
  DisplayFileAge(arg(0)) 'VBS

  C:\_D\TEST>date /t
  09.10.2008
  C:\_D\TEST>cmdfaq "My test file.txt"
  05.09.2008  20:03                51 My test file.txt
  "My test file.txt" is 34 days old

To get the ages of all the files in a folder
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Set the target folder
  set foldername_=C:\_D\BAS
  if not exist "%foldername_%\" (
    echo Folder "%filename_%" not found
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%foldername_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

  Function PadLeftFn(Str,Places) 'VBS
    Dim s 'VBS
    For i = 1 To Places-1 'VBS
      s = s & " " 'VBS
    Next 'VBS
    PadLeftFn = Mid(s & Str, Len(Str), Places) 'VBS
  End Function 'VBS

  Function FileAgeFn(filename) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFile(filename) 'VBS
    FileAgeFn = DateDiff("d", f.DateLastModified, currentdate) 'VBS
  End Function 'VBS

  Sub TraverseOneFolder(foldername) 'VBS
  Dim fso, f, f1, fc 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set f = fso.GetFolder(foldername) 'VBS
  Set fc = f.Files 'VBS
  For Each f1 in fc 'VBS
    Wscript.Echo PadLeftFn(FileAgeFn(f1),6) & " " & f1 'VBS
  Next 'VBS
  End Sub 'VBS

  ' The VBS main program
  currentdate = Date 'VBS
  set arg = WScript.Arguments 'VBS
  TraverseOneFolder(arg(0)) 'VBS

The output displaying the files' ages could be e.g.
  C:\_D\BAS>cmdfaq
    1328 C:\_D\BAS\BATFAQ.BAS
    2137 C:\_D\BAS\BATFAQ3.BAT
       0 C:\_D\BAS\CMDFAQ.CMD
    1400 C:\_D\BAS\FAQPAS.PAS
      34 C:\_D\BAS\My test file.txt
     165 C:\_D\BAS\My test file2.txt
     184 C:\_D\BAS\Test & (5!).txt
    1081 C:\_D\BAS\TEST.VBS

What if we wish to traverse the subfolders as well?
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Set the target parent folder
  set foldername_=C:\_D
  if not exist "%foldername_%\" (
    echo Folder "%filename_%" not found
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%foldername_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

  Function PadLeftFn(Str,Places) 'VBS
    Dim s 'VBS
    For i = 1 To Places-1 'VBS
      s = s & " " 'VBS
    Next 'VBS
    PadLeftFn = Mid(s & Str, Len(Str), Places) 'VBS
  End Function 'VBS

  Function FileAgeFn(filename) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFile(filename) 'VBS
    FileAgeFn = DateDiff("d", f.DateLastModified, currentdate) 'VBS
  End Function 'VBS

  Sub TraverseOneFolder(foldername) 'VBS
    Dim fso, f, f1, fc 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(foldername) 'VBS
    Set fc = f.Files 'VBS
    For Each f1 in fc 'VBS
      Wscript.Echo PadLeftFn(FileAgeFn(f1),6) & " " & f1 'VBS
    Next 'VBS
  End Sub 'VBS

  Sub TraverseManyFolders(startfoldername) 'VBS
    Dim fso, f, f1, sf 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(startfoldername) 'VBS
    If Instr (1, Ucase(f), "RECYCLER") = 0 Then 'VBS
      TraverseOneFolder(f) 'VBS
    End If 'VBS
    Set sf = f.SubFolders 'VBS
    For Each f1 in sf 'VBS
      If Instr (1, Ucase(f1), "RECYCLER") = 0 Then 'VBS
        TraverseManyFolders(f1) 'VBS
      End If 'VBS
    Next 'VBS
  End Sub 'VBS

  ' The VBS main program
  currentdate = Date 'VBS
  set arg = WScript.Arguments 'VBS
  TraverseManyFolders(arg(0)) 'VBS

The output could be e.g.
  C:\_D\BAS>cmdfaq|sort
       0 C:\_D\BAS\CMDFAQ.CMD
       0 C:\_D\BAS\CMDFAQ2.CMD
       1 C:\_D\ACCOUNTS\2008\TOP0484A.PGP
       1 C:\_D\ACCOUNTS\APUTILI.PGP
       1 C:\_D\TEACHING\JOTT\MAILNEWS\JOTT.MAI
       1 C:\_D\TEACHING\JOTT\TUL\JOTTOS.XLS
       :
    8418 C:\_D\QL\BASPROG\GRAPDEMO.BAS
    8418 C:\_D\QL\BASPROG\TURTDEMO.BAS
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:46 2011
Subject: 46) Is a program available in the default folder or at path?
Date: Mon, 31 Jan 2011 01:00:46
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions disabledelayedexpansion
  set find_=gawk.exe
  set found_=
  for %%f in ("%find_%") do set found_="%%~$PATH:f"
  if exist "%find_%" set found_="%find_%"
  if [%found_%]==[""] (
    echo "%find_%" not found at path or in the current folder
    goto :EOF)
  echo Found %found_%
  endlocal & goto :EOF
The output would be e.g.
  C:\_D\TEST>cmdfaq
  Found "c:\_F\FTOOLS\gawk.exe"
or
  "gawk.exe" not found at path or in the current folder

Or, written as a subroutine
  @echo off & setlocal enableextensions
  call :IsAtPath "gawk.exe" file_
  if not defined file_ echo File not found
  if defined file_ echo Found %file_%
  endlocal & goto :EOF
  ::
  :: ==========================================================
  :IsAtPath SearchFor found_
  setlocal enableextensions disabledelayedexpansion
    set found_=
    for %%f in ("%~1") do set found_="%%~$PATH:f"
    if exist "%~1" set found_="%~1"
    if [%found_%]==[""] set found_=
  endlocal & set "%~2=%found_%" & goto :EOF
It would be advisable to avoid poison characters in the file names to
be searched for.

It can be considered a counterpart of the UNIX "which" command.
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  if [%1]==[] (
    echo Usage: %~0 [Filename]
    goto :EOF)
  ::
  if not [%2]==[] (
    echo Usage for long file names: %~0 ["Filename"]
    goto :EOF)
  ::
  set target_=%~1
  ::
  for %%f in ("%target_%") do set where_="%%~$PATH:f"
  if exist "%target_%" set where_="%cd%\%target_%"
  if [%where_%]==[""] (
    echo "%target_%" not found at path or current folder
    ) else (
    set where_=!where_:"=!
    echo where_=!where_!)
  ::
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq ssh2.exe
  where_=C:\Program Files\SSH Communications Security\SSH Secure Shell\ssh2.exe

References/Comments:
 http://www.google.com/groups?selm=nbh5i1tglbr6o3vml87avvta7v2c99et59%404ax.com
 http://www.google.com/groups?selm=729hi11m33e4548s35rbhtli6hvlgesu4d%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:47 2011
Subject: 47) Is it possible to echo the redirection symbol in a script?
Date: Mon, 31 Jan 2011 01:00:47
From: ts@uwasa.fi (Timo Salmi)

There are several examples to that effect throughout the FAQ at hand.
Just search through this file for instances of the caret ^ escape
character.*)  Note that on occasion the caret can also be used to
continue a command line (see e.g. item #6).

*)The caret is the regular escape character in cmd.exe command line
programming. However, depending on the circumstances the escape
character can (or must) be %, "" or \ as will be seen in the some of
the examples below.

An example of echoing the pipe symbol:
  @echo off & setlocal enableextensions disabledelayedexpansion
  echo |Hello World!|
  endlocal & goto :EOF
will produce
  C:\_D\TEST>cmdfaq
  The syntax of the command is incorrect.
while
  @echo off & setlocal enableextensions disabledelayedexpansion
  echo ^|Hello World!^|
  endlocal & goto :EOF
will produce
  C:\_D\TEST>cmdfaq
  |Hello World!|
Also note the option of using the following to produce the same result
  @echo off & setlocal enableextensions enabledelayedexpansion
  echo ^|Hello World^^!^|
  endlocal & goto :EOF

It is not the only method, though, as reminded in
http://www.google.com/groups?selm=bsnpio%24eo2ml%241%40ID-55492.news.uni-berlin.de
The line below is an exact extract from that message:
  <nul (set /p z="<this>|<is>|<only>|<a>|<TEST>")>out.txt

A second option to produce the said text is
  for %%a in ("<this>|<is>|<only>|<a>|<TEST>") do echo %%~a
which also will give you
  <this>|<is>|<only>|<a>|<TEST>

The difference is that the set /p method will not produce a new line
while the second one will.

One way of producing any character is using G(nu)AWK. For example,
to produce the pound symbol () Hex 9C apply
  gawk 'BEGIN{print "\x3E\n"}'
or
  gawk "BEGIN{print \"\x3E\n\"}"
Note in the latter that in the UNIX-originating gawk the escape
character is \ not ^

Likewise, VBScript could be used
  @echo off & setlocal enableextensions
  >"%temp%\tmp$$$.vbs" echo WScript.Echo "Redirection symbol >"
  cscript //nologo "%temp%\tmp$$$.vbs"
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & goto :EOF
The output would be
  C:\_D\TEST>cmdfaq
  Redirection symbol >

Also the methods presented in the MS-DOS+Win..95/98/ME FAQ item
 "38) Is it possible to echo the redirection symbol in a batch?"
 ftp://garbo.uwasa.fi/pc/link/tsbat.zip
should work. But these are just additional, complicated ways of
doing what is already covered by the ^ escape character.

Furthermore, consider the following example demonstrating a difference
between MS-DOS+Win../95/98/Me COMMAND.COM batches and NT/2000/XP
CMD.EXE scripts. The user wishes to echo the ampersand (&)
character. For the former neither the caret ^ nor the ampersand &
has a special meaning while for the latter they do. For CMD.EXE the
caret in the escape character and the ampersand &  the multiple
commands on one command line character. Thus given
  @echo off
  echo &
  echo ^&
MS-DOS+Win../95/98/Me will produce
  &
  ^&
while NT/2000/XP will produce
  ECHO is off.
  &
Hence for NT/2000/XP the solution is
  @echo off
  echo Echoing the ^& ampersand

The NT/2000/XP special characters which require escaping are
<space>&()[]{}^=;!'+,`~

Let's take an example. How does one echo the following from within a
command script?
  ^null@uwasa\.fi$
The answer
  @echo off & setlocal enableextensions
  rem Alternative 1
  echo ^^null@uwasa\.fi$
  rem Alternative 2
  for %%i in ("^null@uwasa\.fi$") do echo %%~i
  endlocal & goto :EOF

One alternative, just for demonstration, is
  @echo off & setlocal enableextensions %void%
  goto MainScript %void%
  ^null@uwasa\.fi$
  :MainScript %void%
  findstr /v /c:"void" "%~0" %void%
  endlocal & goto :EOF %void%
The output
  C:\_D\TEST>cmdfaq.cmd
    ^null@uwasa\.fi$

Escaping must be done the right number of times. For example
  @echo off & setlocal enableextensions
  for %%i in ("yes ^& no") do echo %%~i
  endlocal & goto :EOF
will produce
  yes ^& no
because the quotes already effect the escaping once. That same output
would, of course, also be produced by
  @echo off & setlocal enableextensions
  echo yes ^^^& no
  endlocal & goto :EOF
demonstrating the need to escape exactly the right number of times to
get the results one may be striving at.

A question from microsoft.public.win2000.cmdprompt.admin:
  I (Tom) am trying to have a BAT file generate another BAT file. In
  that target BAT file, I would like to write values like:

    CALL MyBatFile.bat %1 %2 > MyTargetOutputFile

  I tried executing the following command...

    echo "CALL MyBatFile.bat %1 %2 > MyTargetOutputFile" >> NewBatFile.bat

  Of course the %1 and %2 are getting substituted (I just want the
  literal values %1 and %2 written).  Furthermore the first > tries
  to pipe the output to MyTargetOutputFile (I also wanted ">
  MyTargetOutputFile" to be written to the NewBatFile.bat. Is there
  any way to do what I want?

The answer:
  echo CALL MyBatFile.bat %%1 %%2 ^> MyTargetOutputFile >> NewBatFile.bat

A somewhat similar question to echoing a redirection character is the
question how to echo a % from within a script.
  @echo off
  echo Give it a 100%%
The output
  C:\_D\TEST>cmdfaq
  Give it a 100%

Consider another special demonstration
  @echo off
  echo "&"
  set /a decand_=121 "&" 145
  echo %decand_%

The output will be
  C:\_D\TEST>cmdfaq
  "&"
  17
Why the 17? Because "&" is an escaped bitwise AND as per e.g. item
#102.

Still a further example of an "irregular" escape character in cmd.exe
command line programming:
  @echo off & setlocal enableextensions
  findstr /a:0E /s /p /i "\-x.*\"\*\.\*\"" C:\_G\*.HTM
  endlocal & goto :EOF
The ouput could be e.g.
  C:\_D\TEST>cmdfaq
  C:\_G\WWW\INFO\tscmd047.htm
  C:\_G\WWW\INFO\tscmd098.htm
The cases matched in the above example were -x"*.*" and -x "*.*"

Question:
> I have a file (saytest.txt) which includes the following line
>   3EPlus v4.0 (C:\Program Files\3EPlus4\)
>How do I match it with FINDSTR? It does not seem to work.

This is exactly what has been covered in this item. It is about the
escape characters. The relevant search is
  findstr /c:"3EPlus v4.0 (C:\\Program Files\\3EPlus4\\)" test.txt

Consider a real-life example involving among other things echoing <
and >. The task is about converting between the email address book
formats of different programs.

In the address book of the UNIX elm the format of an invidiual adress
is
  tsuvasa     = Timo Salmi = ts@uvasa.fi
In Thunderbird the format is the very common
  Timo Salmi <ts@uvasa.fi>
and in the CSV (Microsoft Excel Comma Separated Values File) format
  ,,Timo Salmi,,ts@uvasa.fi,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Given an elm address book, the task is 1) to pick an address based on
the first field (called the alias) and to convert the found address
into 2) the Thunderbird compliant format, and 3) the CSV format.

  @echo off & setlocal enableextensions
  echo +----------------------------------------------------+
  echo  ELMC.CMD Expand a UNIX elm email alias             
  echo  By prof. Timo Salmi, Last modified Sat 22-Nov-2008 
  echo +----------------------------------------------------+
  echo.

  :: Set the relevant environment variables
  set vbs_=%temp%\tmp$$$.vbs
  set source_=C:\ELM\ALIASES.TEXT
  set alias_=%~1

  :: Is help asked for
  if "%~1"=="" goto _help
  if "%~1"=="?" goto _help
  if "%~1"=="/?" goto _help

  :: Is the alias present in the aliases file
  findstr /b /i /c:"%alias_% " "%source_%">nul
  if %errorlevel% GTR 0 (
    echo Alias %alias_% not found in "%source_%"
    goto _out)

  :: Echo the relevant line from the elm aliases file
  findstr /b /i /c:"%alias_% " "%source_%"

  :: Establish the name and the address, untrimmed, allow apostrophes
  for /f "tokens=2-3 usebackq delims==" %%a in (`
    findstr /b /i /c:"%alias_% " "%source_%"`) do (
      set name_=%%a
      set addr_=%%b)

  :: Remove any quote (") characters
  set name_=%name_:"=%
  set addr_=%addr_:"=%

  :: Trim the name and the address, i.e. remove leading and trailing blanks
  >"%vbs_%" echo WScript.Echo Trim("%name_%")
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%vbs_%"') do set name_=%%a
  >"%vbs_%" echo WScript.Echo Trim("%addr_%")
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%vbs_%"') do set addr_=%%a

  :: Display the results
  for %%a in ("<%addr_%>") do echo %name_% %%~a
  echo ,,%name_%,,%addr_%,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
  goto _out

  :_help
  echo Usage: ELMC alias
  goto _out

  :_out
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>ELMC tsuvasa
  +----------------------------------------------------+
   ELMC.CMD Expand a UNIX elm email alias             
   By prof. Timo Salmi, Last modified Sat 22-Nov-2008 
  +----------------------------------------------------+

  tsuvasa     = Timo Salmi = ts@uvasa.fi
  Timo Salmi <ts@uvasa.fi>
  ,,Timo Salmi,,ts@uvasa.fi,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

References/Comments:
 hh ntcmds.chm::/echo.htm
 http://www.google.com/groups?selm=AVsbk.27291%24_03.26771%40reader1.news.saunalahti.fi
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:48 2011
Subject: 48) Why do some comment lines cause errors? What can I do about it?
Date: Mon, 31 Jan 2011 01:00:48
From: ts@uwasa.fi (Timo Salmi)

Consider the following script
  @echo off & setlocal enableextensions
  rem set var2=%~var1%
  echo We made it!
  endlocal & goto :EOF
While this should work (the second, syntactically incorrect line is
just a comment) the (slightly condensed) output will be
  D:\TEST>cmdfaq
  The following usage of the path operator in script-parameter
  substitution is invalid: %~var1%
  For valid formats type CALL /? or FOR /?
  The syntax of the command is incorrect.

Now why is this? I do not know. I can only speculate. It would
appear that a command line is parsed from the end towards the
beginning. If so, the error is reported before the REM comment
command is reached. That obviously is a bug in the Microsift
NT/2000/XP CMD.EXE command line processor parser.

The following alternatives cause the same error
  @echo off & setlocal enableextensions
  :: set var2=%~var1%
  echo We made it!
  endlocal & goto :EOF
and (c.f. Item #9)
  @echo off & setlocal enableextensions
  rem set var2=%~var1%> nul 2>&1
  echo We made it!
  endlocal & goto :EOF

What can one do about it? The only solution I currently know is an
ugly one:
  @echo off & setlocal enableextensions
  goto _afterComment
  rem set var2=%~var1%
  :_afterComment
  echo We made it!
  endlocal & goto :EOF
Now the output will be as it should:
  D:\TEST>cmdfaq
  We made it!

To still demonstrate that the %~ is at the core of the backwards-parsing catch:
  @echo off & setlocal enableextensions
  rem %~
  echo We've made it
  endlocal & goto :EOF

  D:\TEST>cmdfaq
  The following usage of the path operator in batch-parameter
  substitution is invalid: %~
  For valid formats type CALL /? or FOR /?
  The syntax of the command is incorrect.
while
  @echo off & setlocal enableextensions
  rem %^~
  echo We've made it
  endlocal & goto :EOF

  D:\TEST>cmdfaq
  We've made it

Another similar catch
  @echo off & setlocal enableextensions
  (
    :: Note the empty line below

    echo We've made it
  )
  endlocal & goto :EOF
  D:\TEST>cmdfaq
  The syntax of the command is incorrect.

while

  @echo off & setlocal enableextensions
  :: Note the empty line below

  echo We've made it
  endlocal & goto :EOF
The output:
  D:\TEST>cmdfaq
  We've made it

and

  @echo off & setlocal enableextensions
  (
    rem Note the empty line below

    echo We've made it
  )
  endlocal & goto :EOF
  D:\TEST>cmdfaq
  We've made it

Add to all this the fact that so many
  for (
  ...
    )
and
  if (
  ...
    )

References/Comments:
 http://www.google.com/groups?selm=mzCeKqBCEF5%2BEwff%40ponle.demon.co.uk
 http://www.google.com/groups?selm=Ox1Jb.906684%249l5.799065%40pd7tw2no
 http://www.google.com/groups?selm=e7863ca5-7a4f-4313-b268-78d9e35af7ea%40n3g2000yqb.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:49 2011
Subject: 49) I need to reverse a text file. How do I do that fairly quickly?
Date: Mon, 31 Jan 2011 01:00:49
From: ts@uwasa.fi (Timo Salmi)

Assume e.g. the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

The shortest solution is using a SED one-liner (skips, however, the
empty lines with the old sed version):
  @echo off & setlocal enableextensions
  type "My test file.txt"|sed -n "1!G;h;$p"
  endlocal & goto :EOF
The output
  C:\_D\TEST>cmdfaq
  line 9
  line 8 &()[]{}^=;!'+,`~
  line 7
  line 6 Line 5 is empty!
  line 4
  line 3 <>
  line 2 &()[]{}^=;!'+,`~
  line 1

With a more recent sed
  @echo off & setlocal enableextensions
  unxsed "1!G;h;$!d" "My test file.txt"
  endlocal & goto :EOF

The output
  C:\_D\TEST>cmdfaq
  line 9
  line 8 &()[]{}^=;!'+,`~
  line 7
  line 6 Line 5 is empty!

  line 4
  line 3 <>
  line 2 &()[]{}^=;!'+,`~
  line 1

There are other, longer solutions, which are included for
demonstration. First with G(nu)AWK.
  @echo off & setlocal enableextensions
  set awk_=%temp%\tmp$$$.awk
  set tmf_=%temp%\tmp$$$.txt
  >  "%awk_%" echo {p=length(NR)
  >> "%awk_%" echo lead="000"
  >> "%awk_%" echo lead=substr(lead,1,4-p)
  >> "%awk_%" echo printf"%%s%%s%%s\n",lead,NR,$0}
  ::
  type "My test file.txt"|gawk -f "%awk_%">"%tmf_%"
  type "%tmf_%"|sort /r|gawk -F '{printf "%%s\n",$2}'
  ::
  for %%f in ("%tmf_%" "%awk_%") do if exist %%f del %%f
  endlocal & goto :EOF
The ouput is
  C:\_D\TEST>cmdfaq
  line 9
  line 8 &()[]{}^=;!'+,`~
  line 7
  line 6 Line 5 is empty!

  line 4
  line 3 <>
  line 2 &()[]{}^=;!'+,`~
  line 1

Another version. It does not need the  trick.
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  set tmp1_=%temp%\tmp$$$.txt
  set tmp2_=%temp%\tmp$$2.txt
  gawk '{printf"%%4s %%s\n",NR,$0}' "%myfile_%" > "%tmp1_%"
  <"%tmp1_%" sed -e"s/^   /000/" -e"s/^  /00/" -e"s/^ /0/">"%tmp2_%"
  <"%tmp2_%" sort /r | gawk '{print substr($0,6)}'
  for %%f in ("%tmp1_%" "%tmp2_%") do if exist %%f del %%f
  endlocal & goto :EOF

Also
  @echo off & setlocal enableextensions
  type "My test file.txt"|gawk "{Array[NR]=$0}END{for(x=NR;x!=0;x--)print Array[x]}"
  endlocal & goto :EOF

There is a possibility of a pure script solution. This solution
benefits from a discussion in the news:alt.msdos.batch.nt as per the
earlier item #23. This also introduced the use of FOR /L for the first
time in the original FAQ collection.
  @echo off & setlocal enableextensions
  :: Make a test file
  set fileName=mytest.txt
  for %%f in ("%fileName%" "%temp%\mytemp.txt") do if exist %%f del %%f
  for %%f in (1 2 3 4 5 6 7 8 9) do echo This is line %%f>>"%fileName%"
  ::
  :: Get the number of lines
  for /f %%a in ('find /v /c "" ^< "%fileName%"') do set /a lineCount=%%a
  ::
  :: Loop through the lines of the file from the last line to the first
  for /L %%a in (%lineCount%,-1,1) do call :OutputOneLine %%a
  ::
  :: Clean up
  for %%f in ("%fileName%" "%temp%\mytemp.txt") do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  @echo off & setlocal enableextensions
  :: ============================================
  :OutputOneLine
    set /a StartAt = %1 - 1
    more /e +%StartAt% "%fileName%">"%temp%\mytemp.txt"
    set /p Nth_line=<"%temp%\mytemp.txt"
    echo %Nth_line%
  endlocal & goto :EOF
The output is
  D:\TEST>cmdfaq
  This is line 9
  This is line 8
  This is line 7
  This is line 6
  This is line 5
  This is line 4
  This is line 3
  This is line 2
  This is line 1
However, this solution is not generic! It fails if the file contains "
poison characters" and/or empty lines. (C.f. the first example file.)

A VBS-aided script can be used for a fast and generic, but memory-intensive solution
  @echo off & setlocal enableextensions
  ::
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  <"%myfile_%" cscript //nologo "%vbs_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  ' The Visual Basic Script
  Dim LineArray(1000) 'VBS, increase the dimension if necessary
  ' Read the file from StdIn into an array
  n = 0 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    n = n + 1 'VBS
    LineArray(n) = WScript.StdIn.ReadLine 'VBS
  Loop 'VBS
  ' Write out the the array, reversed
  For i = n To 1 Step -1 'VBS
    WScript.Echo LineArray(i) 'VBS
  Next 'VBS

References/Comments:
 Feb 4  Matthias Tacke   Suggestion for Tscmd 049
 ftp://garbo.uwasa.fi/pc/pd2/tspost28.zip
 Information email + postings, from 19-Sep-00 to ...
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:50 2011
Subject: 50) How do I get the position of a substring in a string?
Date: Mon, 31 Jan 2011 01:00:50
From: ts@uwasa.fi (Timo Salmi)

One potential, pure script solution:
  @echo off & setlocal enableextensions
  rem    01234567890123456789
  set a_=Hello world, Hello.
  set b_=ll
  call :InstrFN "%a_%" "%b_%" position_
  echo The first position of "%b_%" in "%a_%" is %position_%
  endlocal & goto :EOF
  ::
  ::===============================================================
  :: A subroutine to find the first position of a searchstring in a
  :: mainstring. If not found returns -1. If found, the indexing of
  :: the position starts from 0 in accordance with SET conventions.
  ::
  :InstrFN
  setlocal enableextensions enabledelayedexpansion
  ::
  :: Get the mainstring and the searchstring, get rid of possible quotes
  set MainStr=%1
  set MainStr=%MainStr:"=%
  set SearchStr=%2
  set SearchStr=%SearchStr:"=%
  ::
  :: Get the length of the searchstring
  set rest_=%SearchStr%
  set /a SearchLength_=0
  :_length_loop
    set /a SearchLength_+=1
    set rest_=%rest_:~1%
    if defined rest_ goto :_length_loop
  ::
  :: Check for a non-match
  echo %MainStr%|find "%SearchStr%">nul
  if %errorlevel% EQU 1 (endlocal & set /a %3=-1& goto :EOF)
  ::
  :: Match the searchstring with mainstring substrings
  set /a i_=0
  :_position_loop
    if "!MainStr:~%i_%,%SearchLength_%!"=="%SearchStr%" (
      endlocal & set /a %3=%i_%& goto :EOF)
    set /a i_+=1
    goto _position_loop
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  The first position of "ll" in "Hello world, Hello." is 2

There are other solution options:
  @echo off & setlocal enableextensions enabledelayedexpansion
  set a_=Hello world, Hello.
  set b_=ll
  set instr=-1
  for /l %%i in (0,1,255) do (
   set str=!a_:~%%i!
   if defined str (
     echo !str!|findstr /b /l "%b_%">nul
     if !errorlevel! EQU 0 if !instr! EQU -1 set instr=%%i
     )
  )
  echo The first position of "%b_%" in "%a_%" is %instr%
  endlocal & goto :EOF

To find the last position:
  @echo off & setlocal enableextensions
  set a_=Hello world, Hello.
  set b_=ll
  call :InstrLastFN "%a_%" "%b_%" position_
  echo The last position of "%b_%" in "%a_%" is %position_%
  endlocal & goto :EOF
  ::
  :: ============================================================
  :InstrLastFN
  setlocal enableextensions enabledelayedexpansion
  echo %1|findstr %2>nul
  if %errorlevel% EQU 1 (endlocal & set %3=-1& goto :EOF)
  set rest_=%1
  set /a instr_=-1
  :_loop
    set rest_=%rest_:~1%
    echo !rest_!|findstr %2>nul
    if %errorlevel% EQU 1 (endlocal & set %3=%instr_%& goto :EOF)
    set /a instr_ +=1
    goto _loop
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  The last position of "ll" in "Hello world, Hello." is 15

There are other solution options:
  @echo off & setlocal enableextensions enabledelayedexpansion
  set a_=Hello world, Hello.
  set b_=ll
  set instr=-1
  for /l %%i in (0,1,255) do (
   set str=!a_:~%%i!
   if defined str (
     echo !str!|findstr /b /l "%b_%">nul
     if !errorlevel! EQU 0 set instr=%%i
     )
  )
  echo The last position of "%b_%" in "%a_%" is %instr%
  endlocal & goto :EOF

If you can get hold of QBASIC, the first position can also be solved
as follows
  @echo off & setlocal enableextensions
  set a_=Hello world, Hello.
  set b_=ll
  ::
  > tmp$$$.bas echo OPEN "tmp$$$.cmd" FOR OUTPUT AS #1
  >>tmp$$$.bas echo PRINT #1, "@set p_=";LTRIM$(STR$(INSTR("%a_%", "%b_%")))
  >>tmp$$$.bas echo CLOSE #1
  >>tmp$$$.bas echo SYSTEM
  ::
  qbasic /run tmp$$$.bas
  call tmp$$$.cmd
  ::
  echo The position of "%b_%" in "%a_%" is %p_%
  ::
  for %%f in (tmp$$$.bas tmp$$$.cmd) do if exist %%f del %%f
  endlocal & goto :EOF

The output will be (note the different indexing!)
  D:\TEST>cmdfaq
  The position of "ll" in "Hello world, Hello." is 3

Alternatively, a Visual Basic aided command line script solution
could be used:
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  findstr "'VBS" "%~f0"|findstr /v "findstr" > tmp$$$.vbs
  ::
  set a_=Hello world, Hello.
  set b_=ll
  ::
  :: Run the Visual Basic Script
  cscript //nologo tmp$$$.vbs
  ::
  :: Run the auxiliary CMD script
  call tmp$$$.cmd
  ::
  echo The position of "%b_%" in "%a_%" is %p_%
  ::
  for %%f in (tmp$$$.vbs tmp$$$.cmd) do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8       'VBS
  Dim a, b, p, FSO, fout                                       'VBS
  Set WshShell = WScript.CreateObject("WScript.shell")         'VBS
  a=WshShell.ExpandEnvironmentStrings("%a_%")                  'VBS
  b=WshShell.ExpandEnvironmentStrings("%b_%")                  'VBS
  p = Instr(1, a, b, vbTextCompare)                            'VBS
  Set FSO = CreateObject("Scripting.FileSystemObject")         'VBS
  Set fout = FSO.OpenTextFile("tmp$$$.cmd", ForWriting, true)  'VBS
  fout.WriteLine "@set p_=" & p                                'VBS

The output would (again) be
  D:\TEST>cmdfaq
  The position of "ll" in "Hello world, Hello." is 3

More concisely
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  set a_=Hello world, Hello.
  set b_=ll
  ::
  :: Run the Visual Basic Script
  for /f %%p in ('
    cscript //nologo "%vbs_%" "%a_%" "%b_%"') do (
      set p_=%%p)
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Display the result
  echo The position of "%b_%" in "%a_%" is %p_%
  endlocal & goto :EOF
  '
  '...............................................
  'The Visual Basic Script
  '
  set arg = WScript.Arguments 'VBS
  a = arg(0) 'VBS
  b = arg(1) 'VBS
  Wscript.Echo Instr(1, a, b, 1) 'VBS

Or even more concisely
  @echo off & setlocal enableextensions
  ::
  set a_=Hello world, Hello.
  set b_=ll
  ::
  :: Build and run a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" echo Wscript.Echo Instr(1, "%a_%", "%b_%", 1)
  for /f %%p in ('cscript //nologo "%vbs_%"') do set p_=%%p
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Display the result
  echo The position of "%b_%" in "%a_%" is %p_%
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=bt7fqj%24475f4%241%40ID-55492.news.uni-berlin.de
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:51 2011
Subject: 51) How can I echo lines in different colors in NT scripts?
Date: Mon, 31 Jan 2011 01:00:51
From: ts@uwasa.fi (Timo Salmi)

There is no easy answer. The COLOR command affects the entire screen,
not just the next output. That's not what we want in this item. In
MS-DOS+Win..95/98/ME one can use ANSI.SYS for the task. In NT/2000/XP
it also is possible, but not quite simple. Therefore, let's start with
special solutions. One option is to use "ECHOC.EXE Echo in colors"
tool for the task. It is a Turbo Pascal program included in the tscmd.
zip package. For example one might have

  @echo off & setlocal enableextensions
  echoc 0 14 On black bright yellow
  echo.
  echoc 1 13 On blue bright magenta
  echo.
  echo back to normal
  endlocal & goto :EOF

Another example to facilitate multiple spaces between words (and
also rainbow lines)

  @echo off & setlocal enableextensions
  echoc 0 10 M
  echoc 0 11 y
  echoc 0 0
  echoc 0 0
  echoc 0 12 t
  echoc 0 13 e
  echoc 0 14 s
  echoc 0 15 t
  echo.
  endlocal & goto :EOF

For a map of the colors apply COLORMAP.CMD included in tscmd.zip.

If you can get hold of QBASIC, using colors is relatively easy and
much faster. Below is an example
  @echo off & setlocal enableextensions
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  set skip=
  findstr "'%skip%QB" "%~f0" > %temp_%\tmp$$$.bas
  qbasic /run %temp_%\tmp$$$.bas
  for %%f in (%temp_%\tmp$$$.bas) do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  CLS                                              'QB
  COLOR 14,0                                       'QB
  PRINT "A simple ";                               'QB
  COLOR 13,0                                       'QB
  PRINT "color ";                                  'QB
  COLOR 14,0                                       'QB
  PRINT "demonstration"                            'QB
  PRINT "By Prof. Timo Salmi"                      'QB
  PRINT                                            'QB
  FOR j = 0 TO 7                                   'QB
    FOR i = 0 TO 15                                'QB
      COLOR i, j                                   'QB
      PRINT LTRIM$(STR$(i)); " "; LTRIM$(STR$(j)); 'QB
      COLOR 1, 0                                   'QB
      PRINT " ";                                   'QB
    NEXT i                                         'QB
    PRINT                                          'QB
  NEXT j                                           'QB
  SYSTEM                                           'QB

Best of all, however, there is a clever trick to get the ANSI.SYS
color codes in XP based on a tip in alt.msdos.batch.nt
  @echo off & setlocal enableextensions
  ::
  :: The file paths
  set ConfigNT=%WinDir%\System32\config.nt
  set ConfigNTbak=%WinDir%\System32\config.nt.bak
  ::
  :: Check that you have a backup of your original CONGIF.NT
  if not exist "%ConfigNTbak%" (
    echo.
    echo Exiting %~f0
    echo "%ConfigNTbak%"
    echo File not found. Needed for restoring config.nt so first run
    echo copy "%ConfigNT%" "%ConfigNTbak%"
    goto :EOF
    )
  ::
  :: Make a copy of the backup as a double safety
  copy "%ConfigNTbak%" "%temp%\CONFIG.NT">nul
  ::
  :: Customize CONFIG.NT to use ANSI.SYS
  > "%ConfigNT%" echo DOSONLY
  >>"%ConfigNT%" echo dos=high, umb
  >>"%ConfigNT%" echo device=%%SystemRoot%%\system32\himem.sys
  >>"%ConfigNT%" echo files=40
  >>"%ConfigNT%" echo DEVICE=%WinDir%\System32\ANSI.SYS /x
  ::
  :: Choose MS-DOS color
  cls
  command /cecho [0;40;36;1mThis should appear in cyan [0;40;31;1mthis in red
  ::
  :: Restore the original CONFIG.NT
  copy "%temp%\CONFIG.NT" "%WinDir%\System32\">nul
  if exist "%temp%\CONFIG.NT" del "%temp%\CONFIG.NT">nul
  ::
  :: Check if loading ANSI was successful
  mem /c | find /i " ansi ">nul
  if %errorlevel% GTR 0 (
    echo.
    echo Warning: ANSI not loaded
    )
  endlocal & goto :EOF

After successfully running the above script in the CMD.EXE ANSI
escape sequences can be used in the other scripts applying the
following format of the echo
  command /cecho TheAnsiSequence + WhateverText

A demonstration with ANSI.SYS generated colors
  @echo off & setlocal enableextensions enabledelayedexpansion
  cls
  set cecho_=command /cecho
  for /l %%i in (0,1,7) do (
    for /l %%j in (2,1,9) do (
      set /a k=%%j-2
      %cecho_% [%%j;%%i1H[4!k!;3%%im[4!k!;3%%i;1m
      )
    )
  %cecho_% [40;30;1mThe end of the demo by Prof. Timo Salmi
  endlocal & goto :EOF

Another, similar demo:
  @echo off & setlocal enableextensions
  set cecho=echo
  mem /c | find /i " ansi ">nul
  if %errorlevel% EQU 0 (
    set cecho=command /cecho
    set fg_red0=[0;31m
    set fg_red=[0;31;1m
    set fg_green0=[0;32m
    set fg_green=[0;32;1m
    set fg_yellow0=[0;33m
    set fg_yellow=[0;33;1m
    set fg_blue0=[0;34m
    set fg_blue=[0;34;1m
    set fg_magenta0=[0;35m
    set fg_magenta=[0;35;1m
    set fg_cyan0=[0;36m
    set fg_cyan=[0;36;1m
    set fg_white0=[0;37m
    set fg_white=[0;37;1m
    )
  %cecho% %fg_red0%fg_red0 %fg_red%fg_red
  %cecho% %fg_green0%fg_green0 %fg_green%fg_green
  %cecho% %fg_yellow0%fg_yellow0 %fg_yellow%fg_yellow
  %cecho% %fg_blue0%fg_blue0 %fg_blue%fg_blue
  %cecho% %fg_magenta0%fg_magenta0 %fg_magenta%fg_magenta
  %cecho% %fg_cyan0%fg_cyan0 %fg_cyan%fg_cyan
  %cecho% %fg_white0%fg_white0 %fg_white%fg_white
  endlocal & goto :EOF

The advantage of the CONFIG.NT method over using an external program
such as my ECHOC.EXE to output in colors is that it is faster. Note
that there are limitations to the screen display modes the method
can handle. The safest and the most obvious is to use to the 80x25
mode.

References/Comments:
 http://www.google.com/groups?selm=bts0me%24e7b%40poiju.uwasa.fi
 http://www.google.com/groups?selm=40F2CE8D.98194BFA%40yahoo.com.au
 http://www.google.com/groups?selm=1178279717.580298.7190%40n76g2000hsh.googlegroups.com
 http://www.google.com/groups?selm=1194012165.466550.283660%40y42g2000hsy.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:52 2011
Subject: 52) How can I enter a password into a variable without echoing it?
Date: Mon, 31 Jan 2011 01:00:52
From: ts@uwasa.fi (Timo Salmi)

This is a task that is best done with the help of Visual Basic
program which the actual CMD script creates. Note that the resultant
password variable is made available to the CMD script since this is
a CMD, not a VBS FAQ.

  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Prompting without linefeed as in Item #15
  echo.|set /p="Password: "
  :: Run the script with Microsoft Windows Script Host Version 5.6
  for /f "tokens=* delims=" %%a in ('
    cscript //nologo "%vbs_%"') do set MyPass1=%%a
  ::
  echo.
  echo.|set /p="Retype  : "
  for /f "tokens=* delims=" %%a in ('
    cscript //nologo "%vbs_%"') do set MyPass2=%%a
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo.
  if "%MyPass1%"=="%MyPass2%" (
    echo The entered password was %MyPass1%
    ) else (
    echo No match)
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Set WshPass = WScript.CreateObject("ScriptPW.Password") 'VBS
  Password=WshPass.GetPassWord() 'VBS
  WScript.Echo PassWord 'VBS

The output would be someting like
  C:\_D\TEST>cmdfaq
  Password:
  Retype  :
  The entered password was whatever

You might find also item #182 of interest.

References/Comments:
 http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/536f3815d59a165
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:53 2011
Subject: 53) How can I quietly test if a disk device is ready or not?
Date: Mon, 31 Jan 2011 01:00:53
From: ts@uwasa.fi (Timo Salmi)

You might first wish to revisit item #9 about suppressing error
messages.
  @echo off & setlocal enableextensions
  ::
  :: Check the usage
  if "%1"=="" (
    echo Usage: %~f0 [DiskDevice:]
    goto :EOF)
  for %%d in (a: b: c: d: e: f: g: h: i: j: k: l: m: n:
              o: p: q: r: s: t: u: v: w: x: y: z:) do (
              if /i "%%d"=="%1" goto _set)
  echo Usage: %~f0 [DiskDevice:]
  echo The DiskDevice must be A: - Z:
  goto :EOF
  ::
  :: Do the testing and set a relevant result environment variable
  :_set
  set ready=true
  dir %1 > "%temp%\tmp$$$.dir" 2>&1
  find "The device is not ready" "%temp%\tmp$$$.dir" > nul
  if %errorlevel% EQU 0 set ready=false
  find "The system cannot find the path specified" "%temp%\tmp$$$.dir" > nul
  if %errorlevel% EQU 0 set ready=false
  ::
  :: Show the result
  if "%ready%"=="true"  echo The device %1 is ready
  if "%ready%"=="false" echo The device %1 is not ready
  ::
  :: Clean up
  if exist "%temp%\tmp$$$.dir" del "%temp%\tmp$$$.dir"
  endlocal & goto :EOF

The output might be e.g.
  D:\TEST>cmdfaq a:
  The device a: is not ready

A VBS-aided solution to test the presense and the state of a drive:
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the Visual Basic Script
  cscript //nologo "%vbs_%" "N:"
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Set arg = WScript.Arguments 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set dc = fso.Drives 'VBS
  driveName=arg(0) 'VBS
  If fso.DriveExists(driveName) Then 'VBS
    WScript.StdOut.Write driveName & " Found" 'VBS
    Set d = fso.GetDrive(fso.GetDriveName(driveName)) 'VBS
    If d.IsReady Then 'VBS
      WScript.StdOut.WriteLine " (Ready)" 'VBS
    Else 'VBS
      WScript.StdOut.WriteLine " (Not ready)" 'VBS
    End If 'VBS
  Else 'VBS
    WScript.Echo driveName & " not found" 'VBS
  End If 'VBS

The output might be e.g.
  C:\_D\TEST>cmdfaq
  N: Found (Not ready)

The following code will list all the devices that are ready
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%d in (a: b: c: d: e: f: g: h: i: j: k: l: m: n:
    o: p: q: r: s: t: u: v: w: x: y: z:) do (
      dir %%d\ > nul 2>&1
      if !errorlevel! EQU 0 echo %%d
    )
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  c:
  d:
  e:

The following code will list all the devices that are present
  @echo off & setlocal enableextensions
  (for %%d in (A B C D E F G H I J K L M
               N O P Q R S T U V W X Y Z) do ^
    @fsutil fsinfo drivetype %%d:) ^
      | find /v "No such Root Directory"
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq
  A: - Removable Drive
  C: - Fixed Drive
  D: - Removable Drive
  E: - Removable Drive
  N: - Removable Drive
  Z: - CD-ROM Drive

The present drives. With a VBS-aided script. Without the drive types.
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the Visual Basic Script
  cscript //nologo "%vbs_%"
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Dim fso, d, dc 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set dc = fso.Drives 'VBS
  For Each d in dc 'VBS
    If d.IsReady = True Then 'VBS
      Wscript.Echo "Drive " & d.DriveLetter & ": (Ready)" 'VBS
    Else 'VBS
      Wscript.Echo "Drive " & d.DriveLetter & ":" 'VBS
    End If 'VBS
  Next 'VBS

The output might be e.g.
  C:\_D\TEST>cmdfaq
  Drive A:
  Drive C: (Ready)
  Drive N:
  Drive T: (Ready)
  Drive Z:

References/Comments:
 http://www.google.com/groups?selm=1p5ama23spm2o%24.p75bwbfnbwep%24.dlg%4040tude.net
 http://www.google.com/groups?selm=0224e300-0337-4973-bb9e-aeac07c09e29%40p39g2000prm.googlegroups.com
 https://www.microsoft.com/technet/scriptcenter/scripts/default.mspx
 https://www.microsoft.com/technet/scriptcenter/scripts/storage/disks/drives/stdvvb29.mspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:54 2011
Subject: 54) How can I get the type of a disk device?
Date: Mon, 31 Jan 2011 01:00:54
From: ts@uwasa.fi (Timo Salmi)

The following code will list all the devices that are present and
their types. Requires administrator privileges.
  @echo off & setlocal enableextensions
  (for %%d in (A B C D E F G H I J K L M
               N O P Q R S T U V W X Y Z) do ^
    @fsutil fsinfo drivetype %%d:) ^
      | find /v "No such Root Directory"
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq
  A: - Removable Drive
  C: - Fixed Drive
  D: - Removable Drive
  E: - Removable Drive
  N: - Removable Drive
  Z: - CD-ROM Drive

Anoter method, another PC
  @echo off & setlocal enableextensions
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  set outfileUnicode=%temp_%\infou.log
  set outfileAnsi=%temp_%\infoa.log
  "C:\Program Files\Common Files\Microsoft Shared\MSInfo\msinfo32.exe" /report "%outfileUnicode%" /categories +componentsstoragedrives
  type "%outfileUnicode%">"%outfileAnsi%"
  findstr "^Drive ^Description" "%outfileAnsi%"
  for %%f in ("%outfileUnicode%" "%outfileAnsi%") do if exist %%f del %%f
  endlocal & goto :EOF
The output might be e.g.
  Drive   A:
  Description     3 1/2 Inch Floppy Drive
  Drive   C:
  Description     Local Fixed Disk
  Drive   D:
  Description     Removable Disk
  Drive   L:
  Description     Network Connection
  Drive   N:
  Description     Removable Disk
  Drive   P:
  Description     Network Connection
  Drive   T:
  Description     Network Connection
  Drive   Y:
  Description     Network Connection
  Drive   Z:
  Description     CD-ROM Disc
For more comprehensive information we could substitute the following
findstr line into the code
  findstr "^Drive ^Description ^Size ^Free\ Space ^Volume\ Name" "%outfileAnsi%"

Utilizing Visual Basic in the CMD script we get:
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Check the usage
  if "%1"=="" (
    echo Usage: %~f0 [DiskDevice:]
    goto :EOF)
  for %%d in (a: b: c: d: e: f: g: h: i: j: k: l: m: n:
              o: p: q: r: s: t: u: v: w: x: y: z:) do (
              if /i "%%d"=="%1" goto _set)
  echo Usage: %~f0 [DiskDevice:]
  echo The DiskDevice must be A: - Z:
  goto :EOF
  ::
  :_set
  set drive_=%1
  ::
  :: Run the Visual Basic Script
  for /f "tokens=*" %%t in ('
    cscript //nologo "%vbs_%" "%drive_%"') do (
      set drivetype_=%%t)
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Show the results
  echo Drive %drive_% is of type %drivetype_%
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Dim FSO, drive, d, dtype                             'VBS
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  drive=WshShell.ExpandEnvironmentStrings("%drive_%")  'VBS
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS
  If Not FSO.DriveExists(drive) Then                   'VBS
    dtype = "Not found"                                'VBS
  Else                                                 'VBS
    Set d = FSO.GetDrive(drive)                        'VBS
    Select Case d.DriveType                            'VBS
      Case 0: dtype = "Unknown"                        'VBS
      Case 1: dtype = "Removable"                      'VBS
      Case 2: dtype = "Fixed"                          'VBS
      Case 3: dtype = "Network"                        'VBS
      Case 4: dtype = "CD-ROM"                         'VBS
      Case 5: dtype = "RAM Disk"                       'VBS
      Case Else dtype = "Not recognized"               'VBS
    End Select                                         'VBS
    If d.IsReady Then                                  'VBS
      dtype = dtype & "; Ready"                        'VBS
    Else                                               'VBS
      dtype = dtype & "; Not ready"                    'VBS
    End if                                             'VBS
  End If                                               'VBS
  WScript.Echo dtype                                   'VBS

The output could be e.g.
  D:\TEST>cmdfaq P:
  Drive P: is of type Network; Not ready

A pure script method, but (again) requiring administrator privileges,
to test e.g. for a CD-ROM drive is
  @echo off & setlocal enableextensions
  (fsutil fsinfo drivetype Z:|find "CD-ROM Drive">nul)^
    && echo Z: is a CD-ROM Drive || echo Z: is not a CD-ROM Drive
  endlocal & goto :EOF

The output could be e.g.
  D:\TEST>cmdfaq
  Z: is a CD-ROM Drive

A related question. How does one detect the drive letter of the
CD-ROM drive on a PC? This method works only if you are logged on as
"an administrator or a member of the Administrators group".
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%d in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    %comspec% /c if exist %%d:\ (
      fsutil fsinfo drivetype %%d:|find "CD-ROM Drive">nul
      if !errorlevel! EQU 0 set cdletter=%%d
    )
  )
  echo CD-ROM found on drive %cdletter%:
  endlocal & goto :EOF

An example of the output:
  C:\_D\TEST>cmdfaq
  CD-ROM found on drive Z:

Another related question. What is the file system of e.g. the C:
drive? As an aside note the possibility of spanning the FOR command
over several lines.
  @echo off & setlocal enableextensions
  for /f "tokens=5" %%a in (
    'fsutil fsinfo volumeinfo C:\^|
      findstr "File System Name"') do (
        echo %%a)
  endlocal & goto :EOF

An example of the output:
  C:\_D\TEST>cmdfaq
  NTFS

Revisit item #53 for testing whether the drive is ready or not, and
for listing the devices that are ready.

References/Comments:
 http://www.google.com/groups?selm=b25ok4$18prhh$1%40ID-156657.news.dfncis.de
 http://www.google.com/groups?selm=ODxmr8bxIHA.5176%40TK2MSFTNGP04.phx.gbl
 http://www.google.com/groups?selm=0224e300-0337-4973-bb9e-aeac07c09e29%40p39g2000prm.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:55 2011
Subject: 55) How to get the creation, last modified and last access of a file?
Date: Mon, 31 Jan 2011 01:00:55
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  :: Get the file name
  if ["%~1"]==[""] (echo Usage: %~f0 FileName & goto :EOF)
  if not exist "%~f1" (echo File "%~f1" not found & goto :EOF)
  set fname_=%~f1
  ::
  :: Display the information
  for /f %%f in ('dir "%fname_%" /s /b /-c /a:-d-s-h') do echo %%~ff
  echo Created:
  for /f "skip=5 tokens=*" %%f in (
    'dir "%fname_%" /tc /-c /a:-d-s-h^|find /v "(s)"') do echo %%f
  echo Last written:
  for /f "skip=5 tokens=*" %%f in (
    'dir "%fname_%" /tw /-c /a:-d-s-h^|find /v "(s)"') do echo %%f
  echo Last accessed:
  for /f "skip=5 tokens=*" %%f in (
    'dir "%fname_%" /ta /-c /a:-d-s-h^|find /v "(s)"') do echo %%f
  endlocal & goto :EOF

Note that depending on the date/time format specified in your
computer's regional settings the output may vary. The output might
be something like
  D:\TEST>cmdfaq batfaq.bat
  D:\TEST\BATFAQ.BAT
  Created:
  14.11.2003  04:06               118 BATFAQ.BAT
  Last written:
  19.02.2004  13:11               118 BATFAQ.BAT
  Last accessed:
  21.02.2004  16:52               118 BATFAQ.BAT

Depending on what exactly we want, the above solution is not
necessarily satisfactory. The VBS assisted solution below put the
information first into accessible environment variables.
Furthermore, it includes the seconds in the file time stamp.

  @echo off & setlocal enableextensions
  ::
  :: Get the file name
  if ["%~1"]==[""] (echo Usage: %~f0 FileName & goto :EOF)
  if not exist "%~f1" (echo File "%~f1" not found & goto :EOF)
  set fname_=%~f1
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the Visual Basic Script
  cscript //nologo "%vbs_%"
  ::
  :: Call the command line script wchich the script host built
  call tmp$$$.cmd
  ::
  :: Clean up
  for %%f in ("%vbs_%" tmp$$$.cmd) do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo %fname_%
  echo Size:          %~z1 bytes
  echo Created:       %fdc%
  echo Last modified: %flm%
  echo Last accessed: %fla%
  ::
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8       'VBS
  Dim FileName, FSO, fin, fout                                 'VBS
  Set WshShell = WScript.CreateObject("WScript.shell")         'VBS
  Set FSO = CreateObject("Scripting.FileSystemObject")         'VBS
  '
  FileName=WshShell.ExpandEnvironmentStrings("%fname_%")       'VBS
  Set fin = FSO.GetFile(FileName)                              'VBS
  '
  Set fout = FSO.OpenTextFile("tmp$$$.cmd", ForWriting, true)  'VBS
  fout.WriteLine "@set fdc=" & fin.DateCreated                 'VBS
  fout.WriteLine "@set flm=" & fin.DateLastModified            'VBS
  fout.WriteLine "@set fla=" & fin.DateLastAccessed            'VBS
  fout.Close                                                   'VBS

The output might be something like
  D:\TEST>cmdfaq batfaq.bat
  D:\TEST\BATFAQ.BAT
  Size:          118 bytes
  Created:       14.11.2003 04:06:54
  Last modified: 19.02.2004 13:11:32
  Last accessed: 21.02.2004 16:52:49

Incidentally, would you have wanted the file size via the VBS
script then e.g.
  fout.WriteLine "@set fsz=" & fin.size                        'VBS

The same VBS could be written slightly differently as:
  @echo off & setlocal enableextensions
  ::
  :: Get the file name
  if ["%~1"]==[""] (echo Usage: %~f0 FileName & goto :EOF)
  if not exist "%~f1" (echo File "%~f1" not found & goto :EOF)
  set fname_=%~f1
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the Visual Basic Script
  for /f "tokens=1-6 delims= " %%a in ('
    cscript //nologo "%vbs_%" "%fname_%"') do (
      set fdc=%%a %%b
      set flm=%%c %%d
      set fla=%%e %%f
      )
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo %fname_%
  echo Created: %fdc%
  echo Last modified: %flm%
  echo Last accessed: %fla%
  ::
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim arg, FileName, FSO, f 'VBS
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS
  '
  Set arg = WScript.Arguments 'VBS
  FileName = arg(0) 'VBS
  Set f = FSO.GetFile(FileName) 'VBS
  '
  Wscript.Echo f.DateCreated & " " & f.DateLastModified & " " & f.DateLastAccessed 'VBS

The output might be something like
  C:\_M>C:\_D\TEST\CMDFAQ.CMD "C:\_D\TEST\My test file.txt"
  C:\_D\TEST\My test file.txt
  Created: 07.05.2008 17:20:59
  Last modified: 23.06.2008 11:03:57
  Last accessed: 06.07.2008 19:04:43
Most often one is after the "Last modified" information.

Now what if one wants the last modified date and time elements
separately into environment variables?
  @echo off & setlocal enableextensions
  ::
  :: Get the file name
  if ["%~1"]==[""] (echo Usage: %~f0 FileName & goto :EOF)
  if not exist "%~f1" (echo File "%~f1" not found & goto :EOF)
  set fname_=%~f1
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the Visual Basic Script
  for /f "tokens=1-6 delims= " %%a in ('
    cscript //nologo "%vbs_%" "%fname_%"') do (
      set yyyy_=%%a
      set mm_=%%b
      set dd_=%%c
      set hh_=%%d
      set mn_=%%e
      set ss_=%%f
      )
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Demonstrate the result
  echo %fname_%
  echo yyyy_=%yyyy_%
  echo mm_=%mm_%
  echo dd_=%dd_%
  echo hh_=%hh_%
  echo mn_=%mn_%
  echo ss_=%ss_%
  ::
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim arg, FileName, FSO, f, d, s 'VBS
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS
  '
  Set arg = WScript.Arguments 'VBS
  FileName = arg(0) 'VBS
  Set f = FSO.GetFile(FileName) 'VBS
  '
  d = f.DateLastModified 'VBS
  s = Year(d) 'VBS
  s = s & " " & Z2(Month(d)) 'VBS
  s = s & " " & Z2(Day(d)) 'VBS
  s = s & " " & Z2(Hour(d)) 'VBS
  s = s & " " & Z2(Minute(d)) 'VBS
  s = s & " " & Z2(Second(d)) 'VBS
  Wscript.Echo s 'VBS
  '
  Function Z2(x) 'VBS
    Z2 = Right("0" & x, 2) 'VBS
  End Function 'VBS

The output might be something like
  C:\_M>C:\_D\TEST\CMDFAQ.CMD "C:\_D\TEST\My test file.txt"
  C:\_D\TEST\My test file.txt
  yyyy_=2008
  mm_=06
  dd_=23
  hh_=11
  mn_=03
  ss_=57

Since all the ingredients are there one now has the tools for
questions like e.g. "How does one plug the modified date/time into a
set of file names?" See Item #178.

Also see
 FILEINFO.CMD "CMD shell for FILEINFO.VBS"
 FILEINFO.VBS "FileInfo Visual Basic Script"

References/Comments:
 http://www.google.com/groups?selm=OvgPX%2BCSR2OAFwIi%40merlyn.demon.co.uk
 http://www.google.com/groups?selm=7a0b20ed%2Dead5%2D474c%2D8a8e%2Def0ca2c1fa60%4034g2000hsf.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:56 2011
Subject: 56) How to find and move more recent files from one folder to another?
Date: Mon, 31 Jan 2011 01:00:56
From: ts@uwasa.fi (Timo Salmi)

Actually, this task is very near what XCOPY /D /V /F /W
C:\SOURCE\*.* C:\TARGET\ does. With one important difference. XCOPY
does not move files. Even if this task could be attempted with the
CMD.EXE tools presented thorughtout this FAQ, the more complicated
and specific a task gets, the batter to resort to use a programming
language or a third party program. A Visual Basic Script XPMOVE.VBS
is  included for the task. Moving files always involves some danger.
Use the material carefully, and as always, at your own risk.

The information provided by XCOPY together with SED and GAWK can be
used to generate a file of commands to make the moves.
  @echo off & setlocal enableextensions
  ::
  :: Source and target folders
  set SourceFolder=C:\_D\BAS
  set TargetFolder=C:\_M
  ::
  :: Target file where to put the generated script
  set cmd_=C:\_M\MoveThem.cmd
  :: An auxiliary file
  set tmpfile_=%temp%\tempfile.lis
  ::
  :: Use xcopy to identify the files to be moved
  xcopy /D /V /F /L "%SourceFolder%\*.*" "%TargetFolder%\" > "%cmd_%"
  :: Quote the file names and drop the last line (number of files)
  sed -e "s/ -\x3e /\x22 \x22/" "%cmd_%"|sed "$d"> "%tmpfile_%"
  :: Put an @echo off at the beginning of the generated command file
  echo @echo off>"%cmd_%"
  :: Build up the move command, include a rem for safety
  gawk '{printf "rem move /-y \"%%s\"\n",$0}' "%tmpfile_%" >> "%cmd_%"
  ::
  :: Clean up
  for %%f in ("%tmpfile_%") do if exist %%f del %%f
  ::
  :: Tell that the generated commands file is ready
  dir "%cmd_%"
  endlocal & goto :EOF
In the above the " -\x3e " means " -> " and a \x22 stands in hex for a
quote character (").

The contents of the generated MoveThem.cmd would be someting like
  @echo off
  rem move /-y "C:\_D\BAS\BATFAQ.BAS" "C:\_M\BATFAQ.BAS"
  rem move /-y "C:\_D\BAS\BATFAQ.BAT" "C:\_M\BATFAQ.BAT"
  rem move /-y "C:\_D\BAS\BATFAQ2.BAT" "C:\_M\BATFAQ2.BAT"
  :

References/Comments:
  hh ntcmds.chm::/xcopy.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:57 2011
Subject: 57) How do I get a list of all my empty folders on c:\ ?
Date: Mon, 31 Jan 2011 01:00:57
From: ts@uwasa.fi (Timo Salmi)

Empty folders, i.e. no files or subfolders. (But first an important
WARNING! Do not go and indiscriminately delete empty folders, since
the system or the programs on your computer may need them.) Here is
one solution option. I first attempted this with a "pure" CMD
script, but because of the possibility of hidden files and hidden
subfolders the results were too unstable.

Note that on a shared or system-managed computer you might get
access denied errors. If so, do not start high up the root of C:\

  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  :: Start from Folder (Customize, if need be)
  set StartFold_=C:\_D
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp%\tmp$$$.vbs"
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & goto :EOF

  Function NumberOfFilesInFolder(FolderName) 'VBS
    Dim fso, f, f1, fc, CountFiles 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(FolderName) 'VBS
    Set fc = f.Files 'VBS
    CountFiles = 0 'VBS
    For Each f1 in fc 'VBS
      CountFiles = CountFiles + 1 'VBS
    Next 'VBS
    NumberOfFilesInFolder = CountFiles 'VBS
  End Function 'VBS

  Function NumberOfFoldersInFolder(FolderName) 'VBS
    Dim fso, f, f1, fc, CountFolders 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(FolderName) 'VBS
    Set fc = f.SubFolders 'VBS
    CountFolders = 0 'VBS
    For Each f1 in fc 'VBS
      CountFolders = CountFolders + 1 'VBS
    Next 'VBS
    NumberOfFoldersInFolder = CountFolders 'VBS
  End Function 'VBS

  Function TraverseSubFolders(StartFolderName) 'VBS
    Dim fso, f, f1, sf, nFil, nFol 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(StartFolderName) 'VBS
    Set sf = f.SubFolders 'VBS
    For Each f1 in sf 'VBS
      nFil = NumberOfFilesInFolder(f1) 'VBS
      nFol = NumberOfFoldersInFolder(f1) 'VBS
      if (CLng(nFil) = 0) And (CLng(nFol) = 0) Then 'VBS
        Wscript.Echo f1 'VBS
      End If 'VBS
      TraverseSubFolders(f1) 'VBS
    Next 'VBS
  End Function 'VBS

  Function TraverseFolders(StartFolderName) 'VBS
    Dim fso, f, f1, sf, nFil, nFol 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    If (fso.FolderExists(StartFolderName)) Then 'VBS
      Set f = fso.GetFolder(StartFolderName) 'VBS
      nFil = NumberOfFilesInFolder(f) 'VBS
      nFol = NumberOfFoldersInFolder(f) 'VBS
      If (CLng(nFil) = 0) And (CLng(nFol) = 0) Then 'VBS
        Wscript.Echo f 'VBS
      End If 'VBS
      TraverseSubFolders(f) 'VBS
    Else 'VBS
      Wscript.Echo "Folder " & StartFolderName & " not found" 'VBS
      Wscript.Quit 'VBS
    End If 'VBS
  End Function 'VBS

  Dim WshShell, StartAtFolder 'VBS
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  StartAtFolder = WshShell.ExpandEnvironmentStrings("%StartFold_%") 'VBS
  TraverseFolders StartAtFolder 'VBS

In pure CMD script one could try
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\_m') do (
    call :DirEmpty "%%d"
    if "!empty_!"=="true" echo %%d)
  endlocal & goto :EOF
  ::
  :: ======================================================
  :DirEmpty
  set empty_=true
  dir %1 /a 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
  if !errorlevel! EQU 0 set empty_=false
  dir %1 /a 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul
  if !errorlevel! EQU 0 set empty_=false
  goto :EOF

However, the above will skip foldername which include an exlamation
mark (!). Thus, alternatively
  @echo off & setlocal enableextensions disabledelayedexpansion
  for /f "tokens=1 delims=" %%d in ('dir /s /b /a:d c:\_m') do (
    call :DirEmpty "%%d")
  endlocal & goto :EOF
  ::
  :: ======================================================
  :DirEmpty
  set empty_=true
  dir %1 /a 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
  if %errorlevel% EQU 0 set empty_=false
  dir %1 /a 2>&1 | find "Dir(s)" | find /v " 2 Dir(s)" > nul
  if %errorlevel% EQU 0 set empty_=false
  if "%empty_%"=="true" echo %1
  goto :EOF

http://www.google.com/groups?selm=v6em6ps8xyh4.mms%40MRC.MIR.SID.75
  @echo off
  for /r \ /d %%a in (*) do (
  dir /b /s /a "%%a"|findstr .>nul
  if errorlevel 1 echo %%a)

With slight adjustments on the inventive original formulation by
Dean Wells in news: microsoft.public.win2000.cmdprompt.admin we can
use
  @echo off & setlocal enableextensions
  dir "C:\MyFolder\*.*" /a /b^
   | find /v "SomeUnlikelyString">nul ^
     && echo NOT empty || echo Empty
  endlocal & goto :EOF
As a sideline, note the usage of the caret ^ for dividing a command
structure over several lines to avoid wrapping problems in
presenting a solution.

Another sideline, about || && and redirection:
  foxidrive wrote:
  > On Mon, 20 Nov 2006 19:14:42 +0200, Timo Salmi <ts@uwasa.fi> of a question made to him:
  >>> setlocal enableextensions
  >>> vol K: |find "48C4-AE69" && echo Backup Samsung || echo Backup Western Digital >>%path_to_start%backup.log
  >>> endlocal
  (Fails. Why?)
  --- end of the forwarded quote ---

  > I can confirm that adding redirection to such a line changes the
  > behavior, and that enclosing the command in ( ) restores it.
  > You can test it with these two lines.
  >
  > (echo b|find "a">nul && echo 0 ||echo 1) >a.txt
  > (echo a|find "a">nul && echo 0 ||echo 1) >a.txt

  Good catch. Some further trials show that same effect can be
  achieved by redirecting the output of the script outside it rather
  than within it. Thus the following also works

    @echo off & setlocal enableextensions
    rem C:\_D\TEST\CMDFAQ.CMD
    echo b|find "a">nul && echo yes|| echo no
    echo a|find "a">nul && echo yes|| echo no
    endlocal & goto :EOF

    C:\_D\TEST>CMDFAQ.CMD > a.txt
  The contents of a.txt will be
    no
    yes

References/Comments:
 http://www.google.com/groups?selm=1j32amiapq3hr%24.g7jzi5lnl8wk%24.dlg%4040tude.net
 hh ntcmds.chm::/ntcmds_shelloverview.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:58 2011
Subject: 58) How do I best combine two quoted arguments into one quoted string?
Date: Mon, 31 Jan 2011 01:00:58
From: ts@uwasa.fi (Timo Salmi)

Consider two cases. First, the arguments are in environment
variables:
  @echo off & setlocal enableextensions
  set x_="C:\Program Files\Schedule\"
  set y_="My log.txt"
  set z1_="%x_:"=%%y_:"=%"
  echo.%z1_%
  goto :EOF
The output will be
  D:\TEST>cmdfaq
  "C:\Program Files\Schedule\My log.txt"

Second, the argument are given as replaceable parameters to the
script:
  @echo off & setlocal enableextensions
  set z2_="%~1%~2"
  echo.%z2_%
  goto :EOF
The output will be
  D:\TEST>cmdfaq "C:\Program Files\Schedule\" "My log.txt"
  "C:\Program Files\Schedule\My log.txt"

The tilde ~ is essential in the second version. As the documentation
about "Using batch parameters" in "Command-line reference" says:
%~1 Expands %1 and removes any surrounding quotation marks ("").

Alternatively, (since e.g. NT4 does not recognize the ~trick) one
could use
  @echo off & setlocal enableextensions
  set x_=%1
  set y_=%2
  set z1_="%x_:"=%%y_:"=%"
  echo.%z1_%
  goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:00:59 2011
Subject: 59) How do I find if a folder exists? How about visible files in it?
Date: Mon, 31 Jan 2011 01:00:59
From: ts@uwasa.fi (Timo Salmi)

Also, and perhaps even first, see the item "75) How do I detect if an
object is a file or a folder?":
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 [FileOrFolderName]
    goto :EOF
    )
  ::
  if not exist "%~1" (
    echo File or folder "%~1" not found
    goto :EOF
    )
  if exist "%~1\" (
    echo "%~1" is a folder
    ) else (
    echo "%~1" is a file
    )
  endlocal & goto :EOF

While the most frequent CLI script question is how to include the date
into a file name, the current first question seems to be the one that
elicits most often inaccurate or outright incorrect answers. The most
robust test in XP for the folder existence is
  if exist "FolderName\" ...

The trick advocated in the Microsoft Command-line reference is
  "if exist c:mydir\nul goto process"
However, the advocated method crumbles with the LFN possibility of
spaces in the folder names. Hence
  if not exist "c:my dir\nul" echo Folder not found
will always be true whether the folder exists or not.

One (further) solution to the problem would appear to be:
  @echo off & setlocal enableextensions
  rem echo on   %This is for debugging purposes%
  ::
  :: Which folder to examine (customize the path!)
  set dr_=c:\my dir
  ::
  if not exist "%dr_%\*.*" (
    echo Folder "%dr_%" not found)
  ::
  if exist "%dr_%\*.*" (
    echo Folder "%dr_%" exists)
  ::
  dir "%dr_%" 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
  if %errorlevel% NEQ 0 (
    echo No visible files in folder "%dr_%")
  ::
  dir "%dr_%" 2>&1 | find "File(s)" | find /v " 0 File(s)" > nul
  if %errorlevel% EQU 0 (
    echo Visible files in found in folder "%dr_%")
  ::
  endlocal & goto :EOF

Phil Robyn pointed out in email that leaving out the \nul the
following kind of a formulation works.
  if not exist "%dr_%" (
    echo Folder "%dr_%" not found
    goto :EOF)

Yet another option is to utilize the fact that short file names do
not have a problem with \nul
  @echo off & setlocal enableextensions
  :: Which folder to examine (customize the path!)
  set dr_=m:\my dir
  :: Test it
  for /f "tokens=1 delims=" %%d in ("%dr_%") do (
    if exist %%~sd\nul (
     echo Found %%d
      ) else (
     echo Did not find %%d))
  endlocal & goto :EOF

To recount an important difference from MS-DOS+Win../95/98/Me batches
  if exist "FolderName\*.*" ...
is not the proper test to see whether or not there are visible files
in a folder. With *.* it always is true. Even if
  if exist "FolderName\*.txt" ...
works as expected.
To test for the empty or not status of a folder use the errorlevel
solution further up.

Also see the items "75) How do I detect if an object is a file or a
folder?" and "5) How do I get a fully qualified path name of my script?"

Finding a file anywhere on a drive is covered in WHEREIS.CMD
Likewise, for folders one can write e.g.
  @echo off & setlocal enableextensions
  set findDir=TEST
  dir /a:d/s/b "C:\%findDir%"
  endlocal & goto :EOF

The output could be something like
  C:\_M>CMDFAQ.CMD
  C:\_D\TUTKIM2\EVA\DATA\TEST
  C:\_G\WWW\NETIKKA\TEST
  C:\_G\WWW\TS\TEST

For more complicated searching one could have e.g.
  @echo off & setlocal enableextensions
  set startDir=C:\_F
  ::
  :: Folders which have at least one digit in the path
  dir /b/s/a:d "%startDir%\"|findstr "[1234567890]"
  pause
  ::
  :: Folders which do not have any digits in the path
  dir /b/s/a:d "%startDir%\"|findstr /v "[1234567890]"
  pause
  ::
  :: Folders which have either 19 or 20 in the path
  dir /b/s/a:d "%startDir%\"|findstr "19" > "%temp%\cmdfaq.tmp"
  dir /b/s/a:d "%startDir%\"|findstr "20">> "%temp%\cmdfaq.tmp"
  for %%c in (type del) do %%c "%temp%\cmdfaq.tmp"
  pause
  ::
  :: Folders which have neither 19 nor 20 in the path
  dir /b/s/a:d "%startDir%\"|findstr /v "19"|findstr /v "20"
  pause
  ::
  :: Folders which have at least four consequtive digits in the path
  dir /b/s/a:d "%startDir%\"|findstr "[0123456789][0123456789][0123456789][0123456789]"
  pause
  ::
  :: Folders which have from 2000 to 2010 in the path
  dir /b/s/a:d "%startDir%\"|findstr "20[01][0123456789]"
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=c2uroi%24pvs%2406%241%40news.t-online.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:00 2011
Subject: 60) How do I delete all but most recent 20 files in a folder?
Date: Mon, 31 Jan 2011 01:01:00
From: ts@uwasa.fi (Timo Salmi)

The example below comes with multiple safeguards. It prepares a new
script, which you then can run. The resulting script comes with
rem:s and the deletion with the /p (prompt for confirmation) switch.
The possibility of file/folder names with spaces has been taken into
account.

  @echo off & setlocal enableextensions
  ::
  :: Which folder to examine (customize the path!)
  set targetdir_=c:\_m\test two
  if not exist "%targetdir_%\*.*" (
    echo Folder "%targetdir_%" not found
    goto :EOF)
  ::
  :: Let the script prepare a new one (customize the path!)
  set script_="c:\_m\doit.cmd"
  if exist %script_% del %script_%
  ::
  :: Identify the files to be deleted
  for /f "skip=20 delims=" %%f in (
    'dir /a:-d /b /o:-d "%targetdir_%\*.*"') do (
      echo rem del /p "%targetdir_%\%%~nf%%~xf">>%script_%)
  ::
  :: Tell me about it
  for /f "delims=" %%s in (%script_%) do if exist %%~fs (
    echo The script "%%~fs" is ready
    echo %%~ts %%~as %%~zs)
  endlocal & goto :EOF

The contents of DOIT.CMD could become e.g.
  rem del /p "c:\_m\test two\CMDFAQ2.CMD"
  rem del /p "c:\_m\test two\test (4!).txt"
  rem del /p "c:\_m\test two\test & 3.txt"
  rem del /p "c:\_m\test two\MYTEST.CMD"
  rem del /p "c:\_m\test two\VBSFAQ.VBS"
  rem del /p "c:\_m\test two\VBSFAQ2.VBS"
  rem del /p "c:\_m\test two\BATFAQ.BAT"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:01 2011
Subject: 61) How can one devise a command line calculator?
Date: Mon, 31 Jan 2011 01:01:01
From: ts@uwasa.fi (Timo Salmi)

There are several options. A fairly trivial, but severely limited
option is using the SET /A command. For example
  @echo off & setlocal enableextensions
  set /a x=4+7
  echo %x%
  endlocal & goto :EOF
The output would be
  D:\TEST>cmdfaq
  11

A second option is using G(nu)AWK. For example
  @echo off & setlocal enableextensions
  gawk 'BEGIN{printf"%%s\n",4/7}'
  endlocal & goto :EOF
The output would be
  D:\TEST>cmdfaq
  0.571429
This option could be used to perform quite complicated calculations.

Of course, one could also have
  @echo off & setlocal enableextensions
  ::
  set find_=gawk.exe
  set found_=
  for %%f in ("%find_%") do set found_="%%~$PATH:f"
  if exist "%find_%" set found_="%find_%"
  if [%found_%]==[""] (
    echo "%find_%" not found at path or in the current folder
    goto :EOF)
  ::
  if not "%~1"=="" goto _calculate
  echo Usage: %~0 Expression
  goto :EOF
  ::
  :_calculate
  gawk 'BEGIN{printf"%%s\n",%*}'
  endlocal & goto :EOF

or much more fully:
  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (call :ProgramTitle & call :ProgramHelp & goto _out)
  if "%~1"=="?" (call :ProgramTitle & call :ProgramHelp & goto _out)
  if "%~1"=="/?" (call :ProgramTitle & call :ProgramHelp & goto _out)
  ::
  set gawk_=GAWK.EXE
  set unxgawk_=UNXGAWK.EXE
  set found1_=
  for %%f in ("%gawk_%") do set found1_="%%~$PATH:f"
  if exist "%gawk_%" set found1_="%gawk_%"
  set found2_=
  for %%f in ("%unxgawk_%") do set found2_="%%~$PATH:f"
  if exist "%unxgawk_%" set found2_="%unxgawk_%"
  if [%found1_%]==[""] if [%found2_%]==[""] (
    call :ProgramTitle
    echo Neither %gawk_% nor %unxgawk_% found at path or in the current folder
    goto _out)
  ::
  "%gawk_%" 'BEGIN{srand();pi=3.14159265358979;printf"%%.15g\n",%*}'
  "%unxgawk_%" "BEGIN{srand();pi=3.14159265358979;printf\"%%.15g\n\",%*}"
  goto _out
  ::
  :ProgramTitle
  echo +-----------------------------------------------------+
  echo ^ GA.CMD Use gawk and unxgawk to perform calculations ^
  echo ^ By Prof. Timo Salmi. Last modified Wed 26-Jan-2011  ^
  echo +-----------------------------------------------------+
  echo.
  goto :EOF
  ::
  :ProgramHelp
  echo Usage: GA Expression
  echo Examples:                          Result
  echo  GA 4 / 7 * 2.5                    1.42857142857143
  echo  GA sqrt(2)                        1.4142135623731
  echo  GA 2**4                           16
  echo  GA exp(4*log(2))                  16
  echo  GA 103 %% 10                      3
  echo  GA exp(1)                         2.71828182845905
  echo  GA log(10)                        2.30258509299405
  echo  GA sin(45*pi/180)                 0.707106781186547
  echo  GA rand()                         0.582076438973693 (e.g.)
  echo  GA int((50-10+1)*rand()+10)       [A random integer 10...50]
  echo  GA strtonum(0xFE)                 254 (unxgawk only)
  echo  GA strtonum(0376)                 254 (unxgawk only)
  echo Further options on the command line:
  echo  Dec to Hex: unxgawk "BEGIN{printf\"%%X\n\",254}"
  echo  Dec to Oct: unxgawk "BEGIN{printf\"%%o\n\",254}"
  echo  Date: unxgawk "BEGIN{printf\"%%s\n\",strftime(\"%%Y%%m%%d %%H%%M%%S\",systime())}"
  goto :EOF
  ::
  :_out
  if not defined cmdbox if defined PauseIfFromDesktop pause
  endlocal & goto :EOF

A third option is using a third-party program such as FN.EXE from
ftp://garbo.uwasa.fi/pc/ts/tsfunc17.zip (or whatever is the current
version number). An example
  D:\TEST>fn sin(45*3.1415926536/180) /b
  0.7071067812

A fourth option is using QBASIC or GWBASIC, if available. For more
see
 FU.BAT Poor man's function evaluator
and the MS-DOS+Win../95/98/ME FAQ ftp://garbo.uwasa.fi/pc/link/tsbat.zip
item "141. Can I calculate factorials in a batch? Do I need
recursion?" which is sufficiently compatible with NT/2000/XP.

A fifth option is letting the CMD.EXE script build a Visual Basic
Script (VBScript)
  @echo off & setlocal enableextensions
  ::
  :: Usage
  set help_=
  if "%~1"=="" set help_=true
  if "%~1"=="?" set help_=true
  if "%~1"=="/?" set help_=true
  if defined help_ (
    echo.+---------------------------------------------------+
    echo ^| CA.CMD Perform Visual Basic calculations          ^|
    echo ^|        in the XP command line window              ^|
    echo ^| By Prof. Timo Salmi, Last modified Tue 3-Jun-2008 ^|
    echo +---------------------------------------------------+
    echo.
    echo Usage: %~f0 Expression
    echo.
    echo.                                       Result
    echo Examples: CA 4 / 7 * 2.5               1.42857142857143
    echo           CA Round^(Sqr^(2^),3^)       1.414
    echo           CA 2^^^^4                    16 [Note the need of double carets ^^]
    echo           CA 103 Mod 10                3
    echo           CA 103 \ 10                  10
    echo           CA Exp^(1^)                  2.71828182845905
    echo           CA Log^(10^)                 2.30258509299405
    echo           CA Sin^(45*Pi/180^)          0.707106781186547
    echo           CA CDbl^(Rnd^)               0.575344264507294
    echo           CA Int^(^(50-10+1^)*Rnd+10^) [A random integer 10...50]
    echo           CA Hex^(254^)                FE
    echo           CA Oct^(254^)                376
    echo           CA 20/4=5                    -1 ^(i.e. true^)
    echo           CA Date-1                    Date yesterday
    if not defined cmdbox if defined PauseIfFromDesktop pause
    goto :EOF)
  ::
  :: File paths
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  if not exist "%temp_%\" (
    echo Working folder %temp_% not found
    echo You may have to recreate it
    goto :EOF
    )
  set vbscalc_=%temp_%\vbscalc.vbs
  set result_=%temp_%\result.txt
  ::
  :: Build a Visual Basic Script
  echo Randomize>"%vbscalc_%"
  echo Const pi=3.14159265358979>>"%vbscalc_%"
  echo WScript.Echo Eval("%*")>>"%vbscalc_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbscalc_%">"%result_%"
  ::
  :: The result from the optional output file
  type "%result_%"
  ::
  for %%f in ("%vbscalc_%" "%result_%") do (
    if exist %%f del %%f)
  endlocal & goto :EOF

The other input/output options include e.g.
  C:\_D\TEST>CA Year(Now)
  2008

  C:\_D\TEST>CA Month(Now)
  6

  C:\_D\TEST>CA Day(Now)
  30

  C:\_D\TEST>CA Weekday(Now)
  2 (Stands for Monday)

  C:\_D\TEST>CA WeekDayName(Weekday(Now), True)
  Mon (The True stands for abbreviate)

  C:\_D\TEST>CA Chr(60)
  <

  C:\_D\TEST>CA Asc("a")
  C:\_M\TEMP\vbscalc.vbs(3, 25) Microsoft VBScript compilation error: Expected ')'


As you can observe the case of trying to return the ANSI character
code corresponding to the first letter in a string produces an error.
However, we can easily write a simple special solution to get the
codes:
  @echo off & setlocal enableextensions
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Asc("%~1")
  cscript //nologo "%temp%\tmp$$$.vbs"
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>CMDFAQ.CMD a
  97
or
  C:\_D\TEST>CMDFAQ.CMD ^<
  60

References/Comments:
 http://www.google.com/groups?selm=IAG%2B8LBTqJYAFwrp%40merlyn.demon.co.uk
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:02 2011
Subject: 62) How can I compare within a script if two files are identical?
Date: Mon, 31 Jan 2011 01:01:02
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  set file1_=c:\_d\test\My test file.txt
  set file2_=c:\_d\test\My test file2.txt
  if not exist "%file1_%" (
    echo File "%file1_%" not found
    goto :EOF)
  if not exist "%file2_%" (
    echo File "%file2_%" not found
    goto :EOF)
  ::
  fc /b "%file1_%" "%file2_%">nul
  echo %file1_%
  echo %file2_%
  if %errorlevel% EQU 0 (
    echo The files agree
    ) else (
    echo The files differ)
  endlocal & goto :EOF

One could also write
  @echo off & setlocal enableextensions
  set file1_=c:\_d\test\My test file.txt
  set file2_=c:\_d\test\My test file2.txt
  echo %file1_%
  echo %file2_%
  fc /b "%file1_%" "%file2_%">nul&&echo Agree||echo Differ
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  c:\_d\test\My test file.txt
  c:\_d\test\My test file2.txt
  Differ

If you have a DIFF.EXE UNIX port that returns an errorlevel, then you
could replace
  fc /b "%file1_%" "%file2_%">nul
with
  diff "%file1_%" "%file2_%">nul

However, if you have an OS version where FC (or DIFF) does not return
an errorlevel then you have to utilize FIND (or FINDSTR) in
conjunction with FC to get the errorlevel.
  @echo off & setlocal enableextensions
  :
  fc /b "%file1_%" "%file2_%"|find "FC: no differences encountered">nul
  :
  endlocal & goto :EOF

Also see Item #7.

References/Comments:
 http://www.google.com/groups?selm=1d6w0ecevgfj7%24.1pxxinkrblmxz.dlg%4040tude.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:03 2011
Subject: 63) How to perform a command on each a line of file as an argument?
Date: Mon, 31 Jan 2011 01:01:03
From: ts@uwasa.fi (Timo Salmi)

Q: I have an argument file with many lines. I want to perform the
same command with the contents of each line in turn as an argument.
How do I do that.

A: Say that you have the following argument file myargs.txt
  row 1
  row 2
  row 3
  row 4
And that you wish to echo (or whatever else) for the argument on
each line in turn.
  @echo off & setlocal enableextensions
  :: The argument file
  set file_=myargs.txt
  if not exist "%file_%" (
    echo File %file_% not found
    goto :EOF)
  ::
  :: Make a temporary folder
  if not exist c:\mytemp mkdir c:\mytemp
  echo @echo off>c:\mytemp\doit.cmd
  ::
  :: Whatever command you wish to perform
  :: The example echoes, that is the second ECHO.
  :: That ECHO command is what you would change to whatever
  for /f "delims=" %%r in ('type "%file_%"') do (
    echo ECHO.%%r>>c:\mytemp\doit.cmd)
  ::
  :: Perform
  call c:\mytemp\doit.cmd
  ::
  :: Clean up
  if exist c:\mytemp\doit.cmd del c:\mytemp\doit.cmd
  rmdir c:\mytemp
  ::
  endlocal & goto :EOF
The contents of your generated, temporary command script file doit.cmd
will have been
  @echo off
  ECHO.row 1
  ECHO.row 2
  ECHO.row 3
  ECHO.row 4
which, when called, results in
  row 1
  row 2
  row 3
  row 4
The same method applies wheter the action you wish to perform on each
argument line is ECHO or something else.

With SED the solution to make c:\mytemp\doit.cmd would be
  @echo off & setlocal enableextensions
  :: The argument file
  set file_=myargs.txt
  if not exist "%file_%" (
    echo File %file_% not found
    goto :EOF)
  ::
  :: Make a temporary folder
  if not exist c:\mytemp mkdir c:\mytemp
  echo @echo off>c:\mytemp\doit.cmd
  ::
  :: Whatever command you wish to perform
  :: The example echoes, that is the second ECHO.
  :: That ECHO command is what you would change to whatever
  sed -e "s/^/ECHO.&/" myargs.txt>c:\mytemp\doit.cmd
  ::
  :: Perform
  call c:\mytemp\doit.cmd
  ::
  :: Clean up
  if exist c:\mytemp\doit.cmd del c:\mytemp\doit.cmd
  rmdir c:\mytemp
  ::
  endlocal & goto :EOF

A similar question from alt.msdos.batch.nt
Let's say I have a simple text file that is e.g. 8 lines long, and
each line contains exactly one number. (Each number can be 1 or 2
digits long.) For example:
  2
  5
  12
  1
  15
  6
  7
  2
How do I script my program to take the 8 numbers in the text file,
then output them to a file that contains exactly one line? Also, I
need each number to be semicolon delimited so that the output looks
like this: 2;5;12;1;15;6;7;2

This is the solution:
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /f %%a in ('type MyFile.txt') do set s_=!s_!%%a;
  set s_=%s_:~0,-1%
  echo %s_%
  endlocal & goto :EOF
The output will be exactly as asked for.

Actually
  for /f %%a in ('type MyFile.txt') do set s_=!s_!%%a;
can be replaced by
  for /f %%a in (MyFile.txt) do set s_=!s_!%%a;
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:04 2011
Subject: 64) How to count the number of lines in a file, empty lines inclusive?
Date: Mon, 31 Jan 2011 01:01:04
From: ts@uwasa.fi (Timo Salmi)

Assume the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

First note that the following pure script will not solve the stated
problem.
  @echo off & setlocal enableextensions
  set myfile_=C:\_D\TEST\My test file.txt
  for /f %%r in ('type "%myfile_%"') do set /a lineCount+=1
  echo The number of lines is %lineCount%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  The number of lines is 8

A pure script solution counting also the empty lines
  @echo off & setlocal enableextensions
  ::
  :: The test file
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: The counting
  for /f "tokens=1 delims=:" %%a in ('
    findstr /n ".*" "%myfile_%"') do (
      set lineCount=%%a)
  ::
  echo The number of lines is %lineCount%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  The number of lines is 9

Another option (pointed out by Phil Robyn):
  @echo off & setlocal enableextensions
  ::
  :: The test file
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: The counting
  for /f %%a in ('
    find /v /c "" ^< "%myfile_%"') do (
      set lineCount=%%a)
  ::
  echo The number of lines is %lineCount%
  endlocal & goto :EOF
If there are several empty lines at the end of the file, the two
methods may not tally.

A gawk solution to the task is very similar and also quite simple and
brief.
  @echo off & setlocal enableextensions
  ::
  :: The test file
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: The counting
  for /f %%a in ('
    type "%myfile_%"^|gawk "{printf \"%%s\n\",NR}"') do (
      set lineCount=%%a)
  ::
  echo The number of lines is %lineCount%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  The number of lines is 9

A Visual Basic Script aided command line script solution
  @echo off & setlocal enableextensions
  ::
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  set cmd_=%temp%\tmp$$$.cmd
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" < "%myfile_%" > "%cmd_%"
  ::
  :: Call the command line script the script host built
  call "%cmd_%"
  ::
  :: Show the result
  echo The number of lines in "%myfile_%" is %lines%
  ::
  :: Clean up
  for %%f in ("%vbs_%" "%cmd_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  i = 0 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    i = i + 1 'VBS
    str = WScript.StdIn.ReadLine 'VBS
  Loop 'VBS
  WScript.StdOut.WriteLine "@set lines=" & i 'VBS
The output will be
  C:\_D\TEST>cmdfaq
  The number of lines in "C:\_D\TEST\My test file.txt" is 9

Alternatively
  @echo off & setlocal enableextensions
  ::
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  for /f "tokens=*" %%a in ('
    cscript //nologo "%vbs_%" "%myfile_%"') do (
      set lines=%%a)
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Show the result
  echo The number of lines in "%myfile_%" is %lines%
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  fileName = WScript.Arguments.Unnamed(0) 'VBS
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS
  Set f = FSO.OpenTextFile(fileName, ForReading, True) 'VBS
  n = 0 'VBS
  Do While Not f.AtEndOfStream 'VBS
    n = n + 1 'VBS
    s = f.ReadLine 'VBS
  Loop 'VBS
  WScript.Echo n 'VBS

References/Comments:
 http://www.google.com/groups?selm=1rzseucveq575%24.53nvvmu63px4.dlg%4040tude.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:05 2011
Subject: 65) How do I add text in front and after each line in a text file?
Date: Mon, 31 Jan 2011 01:01:05
From: ts@uwasa.fi (Timo Salmi)

With G(nu)AWK
  @echo off & setlocal enableextensions
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (1 2 3 4) do (
    echo Line %%f>>myfile.txt)
  echo.>>myfile.txt
  for %%f in (6 7 8 9) do (
    echo Line %%f>>myfile.txt)
  ::
  :: Do it
  <myfile.txt gawk '{printf "Add in front%%sadd after\n",$0}'
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF

With SED
  @echo off & setlocal enableextensions
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (1 2 3 4) do (
    echo Line %%f>>myfile.txt)
  echo.>>myfile.txt
  for %%f in (6 7 8 9) do (
    echo Line %%f>>myfile.txt)
  ::
  :: Do it
  sed -e "s/.*/Add in front&add after/" myfile.txt
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF

With pure script, but skipping the empty lines!
  @echo off & setlocal enableextensions
  :: Make a test file
  for %%f in (myfile.txt) do if exist %%f del %%f
  for %%f in (1 2 3 4) do (
    echo Line %%f>>myfile.txt)
  echo.>>myfile.txt
  for %%f in (6 7 8 9) do (
    echo Line %%f>>myfile.txt)
  ::
  :: Do it
  ::
  :: Clean up
  for %%f in (myfile.txt) do if exist %%f del %%f
  endlocal & goto :EOF

Note how this at the same time answers the question how to remove
empty lines from a text file. One just would apply
  for /f "delims=" %%r in ('type myfile.txt') do (
    echo %%r)
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:06 2011
Subject: 66) How can I delete all the hidden Thumbs.db files from my system?
Date: Mon, 31 Jan 2011 01:01:06
From: ts@uwasa.fi (Timo Salmi)

If you use the "View" | "Thumbnails" option in your Files and
Folders windows, the hidden Thumbs.db system file in each such
folder gradually builds up (if you have not chosen "Do not cache
thumbnails" in Folder Options). To delete them you can use e.g.
following script. It has the option of bypassing the personal
photoalbums folders (mine are at C:\_H\PHOTO and its subfolders.)

  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  echo +-------------------------------------------------------+
  echo ^| THUMBS.CMD Clear the hidden Thumbs.db thumbnail files ^|
  echo ^| By Prof. Timo Salmi, Last modified Fri 18-Jun-2004    ^|
  echo +-------------------------------------------------------+
  ::
  :: Help wanted?
  if /i [%1]==[?] goto _usage
  if /i [%1]==[/?] goto _usage
  ::
  :: Include also the photo folders into the traversing
  if /i [%1]==[all] goto _all
  ::
  :: Ask in general
  set ask_=
  set /p ask_="Traverse some of the hidden Thumbs.db files [y/N]?"
  if /i not "%ask_%"=="y" (endlocal & goto :EOF)
  ::
  :: Delete one by one
  for /f "tokens=* delims=" %%f in (
    'dir /a:h /s /b c:\Thumbs.db^|find /i /v "_h\photo\"') do (
    call :DeleteOneThumb "%%f")
  endlocal & goto :EOF
  ::
  :_all
  :: Ask in general
  set ask_=
  set /p ask_="Traverse ALL hidden Thumbs.db files [y/N]?"
  if /i not "%ask_%"=="y" (endlocal & goto :EOF)
  ::
  :: Delete one by one
  for /f "tokens=* delims=" %%f in (
    'dir /a:h /s /b c:\Thumbs.db') do (
    call :DeleteOneThumb "%%f")
  endlocal & goto :EOF
  ::
  :_usage
  echo.
  echo Usage: THUMBS [all]
  echo        all = traverse also the c:\_h\photo folders
  endlocal & goto :EOF
  ::
  :: =============================================
  :DeleteOneThumb
  dir /a:h %* 2>&1 | find "1 File(s)" > nul
  if %errorlevel% EQU 0 (
    echo.
    for /f "tokens=* delims=" %%f in (%*) do (
      set fsize_=%%~zf
      set fdate_=%%~tf
      set fattr_=%%~af
      )
    echo !fdate_! !fattr_! !fsize_!
    attrib -s -h %* >nul
    del /p %*
    attrib +s +h %* >nul)
  goto :EOF

The output could be something like
  C:\_D\TEST>cmdfaq
  +-------------------------------------------------------+
  | THUMBS.CMD Clear the hidden Thumbs.db thumbnail files |
  | By Prof. Timo Salmi, Last modified Fri 18-Jun-2004    |
  +-------------------------------------------------------+
  Traverse some of the hidden Thumbs.db files [y/N]?y

  04.01.2008 09:27 --ahs---- 4608
  c:\_G\WWW\Thumbs.db, Delete (Y/N)? y

  04.01.2008 08:59 --ahs---- 6144
  c:\_G\WWW\FIGS\Thumbs.db, Delete (Y/N)? y

  04.01.2008 09:27 --ahs---- 8704
  c:\_G\WWW\ICONS\Thumbs.db, Delete (Y/N)? y

The essential trick, since the c:\Thumbs.db are hidden/system files
is to detect them. A straight dir will not do that. The /a:h (or
/a:-d or /a) switch is needed. As an aside note how the /A switch
alone can be interpreted as "ALL", undocumented by DIR /?.

The task could be also done with a single command using DEL to
traverse the disk. (See DEL /?). However, I am a bit reticent about
using such potent methods. Furthermore, the selective exclusion of
groups of files is a problem in this option. Likewise giving the
file size, file date and file attribute information prior asking for
deletion.

References/Comments:
 http://www.google.com/groups?selm=cas9g9%24kt0%2403%241%40news.t-online.com
 http://www.google.com/groups?selm=c2def5%24q1o%40poiju.uwasa.fi
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:07 2011
Subject: 67) Is it possible to send a script variable value to the clipboard?
Date: Mon, 31 Jan 2011 01:01:07
From: ts@uwasa.fi (Timo Salmi)

Get CLIP.EXE from the Windows98 Resource Kit at
ftp://ftp.microsoft.com/Services/TechNet/samples/PS/Win98/Reskit/FILE
or copy a more recent version from Windows Server 2003's C:\%windir%\
system32 folder. AFAIK Vista has a clip.exe, but I have no knowledge
whether it will work on XP. However, the first two will.

  @echo off & setlocal enableextensions disabledelayedexpansion
  set find_=clip.exe
  set found_=
  for %%f in ("%find_%") do set found_="%%~$PATH:f"
  if exist "%find_%" set found_="%find_%"
  if [%found_%]==[""] (
    echo "%find_%" not found at path or in the current folder
    goto :EOF)
  ::
  if not "%~1"=="" goto _clip
  echo Usage: %~0 "Your text"
  goto :EOF
  ::
  :_clip
  echo %~1|clip
  endlocal & goto :EOF

Testing
  C:\_M\TEST>cmdfaq "Timo Salmi tscmd067.htm"
To see what is on the clipboard call C:\WINDOWS\system32\clipbrd.exe
  Timo Salmi tscmd067.htm

However, the above produces an end of line, so the clipboard actually
contains the above text and and an empty line. To avoid that replace
  echo %~1|clip
with
  set /p="%~1"<nul|clip
as per item #15.

Consider one potential application. Send the date and time to the
clipboard. Assumes %time% H:MM:SS.ss
  @echo off & setlocal enableextensions
  set time_=0%time:~0,-6%
  set time_=%time_:~-5%
  set /p datetime="%date% %time_:~0,5%"<nul|clip
  endlocal & goto :EOF
The Clipboard contents e.g.
 14.06.2008 20:30

For two real applications of (optionally) sending material to
clipboard see FULLNAME.CMD and GETFDATE.CMD that come with this
collection.

There are other utilities to transfer date between the command line
window and the clipboard. These include from GNU UnxUtils.zip
  gclip.exe Get Windows clipboard text from stdin
  pclip.exe Put the Windows clipboard text to stdout
and
  clipboard.zip Command Line Clipboard Access software by Steve Kemp.

References/Comments:
 http://blogs.msdn.com/abhinaba/archive/2006/07/14/665551.aspx
 http://www.andyrathbone.com/tips/clipbrd.html
 http://www.google.com/groups?selm=iCr2k.4759$E41.3401%40text.news.virginmedia.com
 http://www.google.com/groups?selm=484cadf5$0$23819$9b536df3%40news.fv.fi
 http://www.steve.org.uk/Software/clipboard/
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:08 2011
Subject: 68) How can I test if a program already has been loaded?
Date: Mon, 31 Jan 2011 01:01:08
From: ts@uwasa.fi (Timo Salmi)

In XP one can use Task Manager for the purpose e.g. as follows

  @echo off & setlocal enableextensions
  tasklist|find "firefox.exe ">nul
  if %errorlevel% EQU 0 (
    echo Firefox has been loaded
  ) else (
    echo Firefox has not been loaded)
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=2u7slvF28684tU1%40uni-berlin.de
References/Comments (for NT/2000):
 http://technet.microsoft.com/en-us/sysinternals/bb896649.aspx

If you are using a script in a command window to call an MS-DOS
program (or a script), and you wish to prevent calling that same
program simultaneously from another window/or via shelling (to avoid
datafile or whatever conflicts), you can proceed as shown below. The
script creates a lockfile for the duration of running the script.

  @echo off & setlocal enableextensions
  if exist "%temp%\vpp3d.mrk" (
    echo Exiting: vpp3d already is running
    echo If this is in error delete %temp%\vpp3d.mrk
    goto :EOF)
  echo Mark vpp3d>"%temp%\vpp3d.mrk"
  ::
  :: Call whatever program it happens to be
  C:\_F\VPP\VPP3D.COM
  ::
  del "%temp%\vpp3d.mrk"
  endlocal & goto :EOF

It is quite possible that there are several cmd.exe windows open and a
script or program running in one of them. Since all are labeled cmd.
exe the question arises how to test if a particular script is being
run. This is how to solve the task:
  @echo off & setlocal enableextensions
  set myscriptIsRrunning_=
  tasklist /v|findstr /b /i /r /c:"cmd.exe.* - myscript">nul
  if %errorlevel% EQU 0 set myscriptIsRunning=true
  if defined myscriptIsRunning (
    echo myscript is currently running
    ) else (
    echo myscript is not currently running)
  endlocal & goto :EOF

References/Comments:
  http://www.google.com/groups?selm=eJp_j.2029$jI5.647%40flpi148.ffdc.sbc.com
  http://www.google.com/groups?selm=452eb6b4%240%2416513%249b536df3@news.fv.fi
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:09 2011
Subject: 69) How do I get the first, or the last, 400 lines of a file?
Date: Mon, 31 Jan 2011 01:01:09
From: ts@uwasa.fi (Timo Salmi)

A question of "head" and "tail" in UNIX terminology. This is a task
that is well suited for SED or for an actual head or tail UNIX port.

The first part concerns "head":
==============================

The easiest solution is to use SED
  @echo off
  sed -n 1,400p myfile.txt

Assume the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  for /f "tokens=* delims=" %%f in ("%myfile_%") do (
    set myfile_=%%~sf)
  sed -n 1,6p "%myfile_%"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!

The renaming to a SFN-format is needed when the SED version usually
assumed in this FAQ is used. However, if the GnuWin32 SED (let us call
it here UNXSED for distinction)  is used, then the LFN/SFN file name
conversion is not needed. Furthermore, head and tail UNIX ports, can
be found on the net, which also could be used in this item.

  @echo off & setlocal enableextensions
  unxsed 6q "My test file.txt"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!

With GnuWin32 G(nu)AWK the solution is
  @echo off & setlocal enableextensions
  set myfile_=My test file.txt
  unxgawk "NR<=6 {printf \"%%s\n\",$0}" "%myfile_%"
  endlocal & goto :EOF

A Visual Basic Script (VBScript) aided command line script version of
"head"
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\vhead.vbs
  for /f "tokens=*" %%f in ("%vbs_%") do set vbs_=%%~sf
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo %vbs_% 6 < "My test file.txt"
  ::
  :: Clean up
  for %%f in (%vbs_%) do del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'The Visual Basic Script for "head"
  '
  StopAfter=WScript.Arguments.Unnamed(0)   'VBS
  i = 0                                    'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine           'VBS
    i = i + 1                              'VBS
    If i <= CInt(StopAfter) Then           'VBS
      WScript.StdOut.WriteLine str         'VBS
    End If                                 'VBS
  Loop                                     'VBS

The output will again be
  C:\_D\TEST>cmdfaq
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>
  line 4

  line 6 Line 5 is empty!

Also pure CMD script solutions can be attempted, but they have
limitations with the empty lines and some of the special characters.
Thus for genric purposes these solutions are not recommended.

Getting just the first line
  @echo off & setlocal enableextensions
  set /p first_=<"My test file.txt"
  echo %first_%
  endlocal & goto :EOF

The output will be
 C:\_D\TEST>cmdfaq
 line 1

  @echo off & setlocal enableextensions disabledelayedexpansion
  set LineCount=0
  for /f "tokens=* delims=" %%r in (
    'type "My test file.txt"') do call :EchoLine "%%r"
  endlocal & goto :EOF
  ::
  :EchoLine
  set /a LineCount+=1
  if %LineCount% GTR 6 goto :EOF
  echo "%~1"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  "line 1"
  "line 2 &()[]{}^^=;!'+,`~"
  "line 3 <>"
  "line 4"
  "line 6 Line 5 is empty!"
  "line 7"
which probably is not quite what we want from a useful solution.

The second part concerns "tail"
===============================

From a sed one-liner's collection by Eric Pement
  sed -e :a -e "$q;N;401,$D;ba" myfile.txt

To get the last six lines (tail -6) of our test file
  @echo off & setlocal enableextensions
  unxsed -e :a -e "$q;N;7,$D;ba" "My test file.txt"
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

A Visual Basic Script (VBScript) aided command line script version of "tail"
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\vtail.vbs
  for /f "tokens=*" %%f in ("%vbs_%") do set vbs_=%%~sf
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo %vbs_% "My test file.txt" 6
  ::
  :: Clean up
  for %%f in (%vbs_%) do del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'The Visual Basic Script
  '
  ' Define some constants
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim fileName, FSO, f, i, n, nArg, s                    'VBS
  '
  ' Check the right usage
  nArg = WScript.Arguments.Count                         'VBS
  If (nArg = 0) Or (nArg > 2) Then                       'VBS
    s = "Usage: cscript //nologo "                       'VBS
    s = s & WScript.ScriptName                           'VBS
    s = s & " fileName [NumberOfLinesFromEnd]"           'VBS
    WScript.Echo s                                       'VBS
    WScript.Quit                                         'VBS
  End If                                                 'VBS
  '
  ' Get the arguments: fileName and tailLines
  fileName=WScript.Arguments.Unnamed(0)                  'VBS
  If WScript.Arguments.Count > 1 Then                    'VBS
    tailLines = CLng(WScript.Arguments.Unnamed(1))       'VBS
  Else                                                   'VBS
    tailLines = 10                                       'VBS
  End If                                                 'VBS
  '
  ' Check that the file exists
  Set FSO=CreateObject("Scripting.FileSystemObject")    'VBS
  if not FSO.FileExists(fileName) Then                  'VBS
    WScript.Echo "File " & fileName & " Not Found"      'VBS
    WScript.Quit                                        'VBS
  End If                                                'VBS
  '
  ' Calculate the number of lines
  Set f = FSO.OpenTextFile(fileName, ForReading, True)  'VBS
  n = 0                                                 'VBS
  Do While Not f.AtEndOfStream                          'VBS
    n = n + 1                                           'VBS
    s = f.ReadLine                                      'VBS
  Loop                                                  'VBS
  '
  ' Output the tail part of the file
  Set f = FSO.OpenTextFile(fileName, ForReading, True)  'VBS
  i = 0                                                 'VBS
  Do While Not f.AtEndOfStream                          'VBS
    i = i + 1                                           'VBS
    s = f.ReadLine                                      'VBS
    If i > n - tailLines Then WScript.Echo s            'VBS
  Loop                                                  'VBS

The output will be
  C:\_D\TEST>cmdfaq
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

However, if we are guaranteed an input file with no blank lines and no poison chracters, then there is a pure CMD script solution for getting the tail of the file. See Item #181 for the code.

What about the other way round? Present all but the first two lines of a text file:
  @echo off & setlocal enableextensions
  more /e +2 "My test file.txt" > "%temp%\tmp$$$.prn"
  type "%temp%\tmp$$$.prn"
  if exist "%temp%\tmp$$$.prn" del "%temp%\tmp$$$.prn"
  endlocal & goto :EOF

  The output will be
  C:\_D\TEST>cmdfaq
  line 3 <>
  line 4

  line 6 Line 5 is empty!
  line 7
  line 8 &()[]{}^=;!'+,`~
  line 9

or with sed
  @echo off & setlocal enableextensions
  unxsed -n 3,$p "My test file.txt"
  endlocal & goto :EOF

Getting all but the last line of a file and getting all but (e.g.) the
last three lines of a file are copvered in item #23.

References/Comments:
 http://www.google.com/groups?selm=d5tcr5%2411eu%241%40agate.berkeley.edu
 http://www.google.com/groups?selm=427dc26a%240%246753%24ed2619ec%40ptn-nntp-reader01.plus.net
 http://www.google.com/groups?selm=tkdi64pvb263b8rf7u9ini6emdbeheo7kv%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:10 2011
Subject: 70) Calendar elements: What weekday was December 31, 2004?
Date: Mon, 31 Jan 2011 01:01:10
From: ts@uwasa.fi (Timo Salmi)

A Visual Basic Script (VBScript) aided command line script solution:
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo WeekDayName(Weekday(DateValue("December 31, 2004")),true)
  for /f %%d in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set wd_=%%d
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo Weekday on December 31, 2004 is wd_=%wd_%
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  Weekday on December 31, 2004 is wd_=Fri

Likewise:
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo DatePart("y",DateValue("December 31, 2004"))
  for /f %%d in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set dn_=%%d
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo The ordinal number day of year on December 31, 2004 is dn_=%dn_%
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  The ordinal number day of year on December 31, 2004 is dn_=366

Further information:
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo DatePart("ww",DateValue("December 31, 2004"),vbMonday,vbFirstFourDays)
  for /f %%w in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set wn_=%%w
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo The week number on December 31, 2004 is wn_=%wn_%
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  The week number on December 31, 2004 is wn_=53

Words of caution about the week number from Dr. John Stockton are in
order. "One cannot trust software of US origin to attempt the ISO
week number, nor to get it right when they do. An ISO 8601 week
number routine needs to return both week and year; both 2004-12-27
and 2005-01-02 will be in Week 2004-53; Week 2004-01 was 2003-12-29
to 2004-01-04. ... Most Americans, AIUI, will want some other
definition entirely. ... The potential users should do a
comprehensive test on their own systems to ensure that the results
given are always correct according to the week number system that
their bosses expect/need.  One should really test Weeks 1, 52 [53]
for all 14 possible year types (leap/non-Leap, starting Mon-Sun)."

An ISO 8601 week number example based on the WeekNumJRS subroutine
provided by John:
  @echo off & setlocal enableextensions
  ::
  :: Set an example date for this demonstration
  set day_=28
  set month_=03
  set year_=2008
  ::
  :: Build a Visual Basic Script
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp_%\tmp$$$.vbs"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%temp_%\tmp$$$.vbs" %year_% %month_% %day_%
  ::
  :: Clean up
  for %%f in ("%temp_%\tmp$$$.vbs") do del "%%~f"
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Sub WeekNumJRS(Tdy, YNo, WNo, DoW) '' Tdy is Date in; Y W D out 'VBS
    Dim N, Thu, SoY '' ISO 8601 Y>=1900 ( because of \ )          'VBS
    N = 2                                                         'VBS
    Thu = ((Tdy+3+N) \ 7) * 7 - N '' Nearest Thu                  'VBS
    YNo = Year(Thu)                                               'VBS
    SoY = DateSerial(YNo, 1, 1) '' Date, YYYY-01-01               'VBS
    WNo = ((Thu - SoY) \ 7) + 1                                   'VBS
    DoW = ((Tdy+5) mod 7) + 1                                     'VBS
  end Sub                                                         'VBS
  '
  Sub MainProgram()                                               'VBS
    set x = WScript.Arguments                                     'VBS
    MyDate = DateSerial(x(0), x(1), x(2))                         'VBS
    WeekNumJRS MyDate, Yno, Wno, DoW                              'VBS
    WScript.Echo "MyDate", MyDate                                 'VBS
    WScript.Echo "Yno", Yno                                       'VBS
    WScript.Echo "Wno", Wno                                       'VBS
    WScript.Echo "DoW", DoW                                       'VBS
  End Sub 'MainProgram                                            'VBS
  '
  MainProgram                                                     'VBS

The output will be
  D:\TEST>cmdfaq
  MyDate 28.03.2008
  Yno 2008
  Wno 13
  DoW 5

Next, consider the question "how many days are there in a month?"
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  if not exist c:\mytemp mkdir c:\mytemp
  findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
  ::
  :: Assume a local date format dd.mm.yyyy
  :: Customize, if necessary
  set month_=2
  set year_=2004
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo c:\mytemp\tmp$$$.vbs
  call c:\mytemp\tmp$$$.cmd
  echo %mmdays_% days in %month_%.%year_%
  ::
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.vbs c:\mytemp\tmp$$$.cmd) do del %%f
  rmdir c:\mytemp
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8                'VBS
  Dim MyDate, mm, yyyy, DaysInMonth, fout, FSO                          'VBS
  '
  Set WshShell = WScript.CreateObject("WScript.shell")                  'VBS
  mm=WshShell.ExpandEnvironmentStrings("%month_%")                      'VBS
  yyyy=WshShell.ExpandEnvironmentStrings("%year_%")                     'VBS
  '
  For i = 28 to 32 'VBS
    Mydate = MonthName(mm, False) & " " & CStr(i) & ", " & CStr(yyyy)   'VBS
    If (IsDate(MyDate)) Then                                            'VBS
      DaysInMonth = i                                                   'VBS
    End If                                                              'VBS
  Next                                                                  'VBS
  '
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS
  Set fout = FSO.OpenTextFile("c:\mytemp\tmp$$$.cmd", ForWriting, true) 'VBS
  fout.WriteLine "@set mmdays_=" & DaysInMonth                          'VBS
  fout.Close                                                            'VBS
The output will be
  D:\TEST>cmdfaq
  29 days in 2.2004

A comment from Dr John Stockton in
http://groups.google.com/groups?selm=3y4RQEGxmaeEFw%2Br%40merlyn.demon.co.uk
  DaysInMonth = Day(DateSerial(yyyy, mm+1, 0)) ' VBS seems simpler

My comment. Yes, indeed. And this goes to show how much a task can be
condensed if written suitably in another way:

  @echo off & setlocal enableextensions
  ::
  :: Test with these
  set month_=2
  set year_=2004
  ::
  :: Get it
  echo>"%temp%\tmp$$$.vbs" WScript.Echo Day(DateSerial(%year_%, %month_%+1, 0))
  for /f %%d in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set mmdays_=%%d
  if exist "%temp%\tmp$$$.vbs" del "%temp%\tmp$$$.vbs"
  ::
  :: Display the result
  echo %mmdays_% days in %month_%.%year_%
  endlocal & goto :EOF

Let's get back to the original problem of getting the weekday. The
problem can also be solved with pure script commands as follows:
(Also see DATEINFO.CMD)
  @echo off & setlocal enableextensions disabledelayedexpansion
  if "%~3"=="" (
    echo Usage: %~0 DD MM YYYY
    echo No leading zeros!
    goto :EOF)
  ::
  set dd_=%~1
  set mm_=%~2
  set yyyy_=%~3
  ::
  set /a a_=(14-%mm_%)/12
  set /a y_=%yyyy_%-%a_%
  set /a m_=%mm_%+12*%a_%-2
  set /a wdnum_=1+(%dd_%+%y_%+%y_%/4-%y_%/100+%y_%/400+(31*%m_%)/12)%%7
  ::
  echo %dd_% %mm_% %yyyy_%
  for /f "tokens=%wdnum_%" %%d in (
    'echo Sun Mon Tue Wed Thu Fri Sat') do set wd_=%%d
  echo %wd_%
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq 31 12 2004
  31 12 2004
  Fri

References/Comments:
 http://www.tondering.dk/claus/cal/node3.html#SECTION00350000000000000000
 http://www.google.com/groups?selm=45d81543%240%2424600%249b536df3%40news.fv.fi
 http://www.merlyn.demon.co.uk/vb-dates.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:11 2011
Subject: 71) How can I reboot my computer from a command line script?
Date: Mon, 31 Jan 2011 01:01:11
From: ts@uwasa.fi (Timo Salmi)

Warmboot in the old MS-DOS terminology. In XP this is really simple.
  @echo off
  shutdown -r

Or, a bit more fully
  @echo off & setlocal enableextensions
  set /p ask_=Restart, are you sure [y/N]?
  if /i not "%ask_%"=="y" if /i not "%ask_%"=="yes" goto :EOF
  @shutdown -r -f -c "Shutting down and restarting from a command line script"
  endlocal & goto :EOF

On a multi-user system you may wish to check if anyone else is logged
on (see item #167) before rebooting.

References/Comments:
  hh ntcmds.chm::/shutdown.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:12 2011
Subject: 72) Is it possible to use quotes as delims in for loops?
Date: Mon, 31 Jan 2011 01:01:12
From: ts@uwasa.fi (Timo Salmi)

The default delimiter set of delims in a FOR /F loop is space and
tab. That can be replaced by defining delims=xxx as the delimiter
set. Assume that we have a data file "myfile.txt"
Line,1,Part,1
Line,2,Part,1
Line,3,Part,1
Line,4,Part,1

Line,6,Part,2
Line,7,Part,2
Line,8,Part,2
Line,9,Part,2

Then
  @echo off & setlocal enableextensions
  set myfile_=myfile.txt
  for /f "tokens=2,4 delims=," %%a in ('type "%myfile_%"') do (
    echo %%a %%b)
  endlocal & goto :EOF
will result in
  1 1
  2 1
  3 1
  4 1
  6 2
  7 2
  8 2
  9 2
Note that the method omits the empty line.

Now, what if instead we had for whatever strange reason in myfile.txt
  Line"1"Part"1
  Line"2"Part"1
  Line"3"Part"1
  Line"4"Part"1

  Line"6"Part"2
  Line"7"Part"2
  Line"8"Part"2
  Line"9"Part"2

Then we would have to take the following steps, first replacing the
quotes (") e.g. with commas (,)
  @echo off & setlocal enableextensions enabledelayedexpansion
  set myfile_=myfile.txt
  ::
  :: Make an auxiliary temporary folder
  if not exist "c:\mytemp" mkdir "c:\mytemp"
  ::
  :: Make sure that the auxiliary file will be build up from scratch
  del "c:\mytemp\tmp$$$.txt" > nul 2>&1
  ::
  :: Echo each line substituting quotes with commas
  for /f "tokens=*" %%c in ('type "%myfile_%"') do (
    set lineContents=%%c
    echo !lineContents:"=,!
    )>>"c:\mytemp\tmp$$$.txt"
  ::
  :: Echo the second and the fourth token on each line
  for /f "tokens=2,4 delims=," %%a in ('type "c:\mytemp\tmp$$$.txt"') do (
    echo %%a %%b)
  ::
  :: Clean up
  for %%f in ("c:\mytemp\tmp$$$.txt") do if exist %%f del %%f
  rmdir "c:\mytemp"
  endlocal & goto :EOF
This will, again, result in
  1 1
  2 1
  3 1
  4 1
  6 2
  7 2
  8 2
  9 2

Alternatively
  @echo off & setlocal enableextensions
  set myfile_=c:\_m\Myfile.txt
  for /f "tokens=2,4 delims=," %%a in ('
    type "%myfile_%"^|sed -e "s/\x22/,/g"') do (
      echo %%a %%b)
  endlocal & goto :EOF

Stepping outside FOR loops, one could use
  @echo off & setlocal enableextensions
  set myfile_=c:\_m\myfile.txt
  <"%myfile_%" gawk -F" '{printf "%%s %%s\n",$2,$4}'
  endlocal & goto :EOF

The output is (now including the empty line)
  1 1
  2 1
  3 1
  4 1

  6 2
  7 2
  8 2
  9 2

Note that the delimiters cannot be strings, only characters, even
though there can be several of them defined in delims=
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:13 2011
Subject: 73) How can I convert a hexadecimal string into an ASCII string?
Date: Mon, 31 Jan 2011 01:01:13
From: ts@uwasa.fi (Timo Salmi)

A Visual Basic Script (VBScript) aided command line script solution:
  @echo off & setlocal enableextensions
  ::
  set HexString=48 65 6C 6C 6F 20 77 6F 72 6C 64 21
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\hexdec.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  :: Run it with Microsoft Windows Script Host Version 5.6
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%vbs_%" "%HexString%"') do set AsciiString=%%a
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Show the result
  echo %HexString%
  echo %AsciiString%
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  set arg = WScript.Arguments 'VBS
  WScript.Echo HexStringToAsciiString(arg(0)) 'VBS
  '
  Function HexStringToAsciiString(HexStr) 'VBS
    For i = 1 To Int(Len(HexStr)/3)+1 'VBS
      str1 = str1 & Chr("&H" & Mid(HexStr,3*i-2,2)) 'VBS
    Next 'VBS
    HexStringToAsciiString=str1 'VBS
  End Function 'VBS

The output will be
  D:\TEST>cmdfaq
  48 65 6C 6C 6F 20 77 6F 72 6C 64 21
  Hello world!

The VBS logic written slightly differently:
  @echo off & setlocal enableextensions
  ::
  set HexString=48 65 6C 6C 6F 20 77 6F 72 6C 64 21
  ::
  :: Build a Visual Basic Script
  if not exist c:\mytemp mkdir c:\mytemp
  findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo c:\mytemp\tmp$$$.vbs>c:\mytemp\tmp$$$.cmd
  ::
  :: Call the CMD script made by the VBS script
  call c:\mytemp\tmp$$$.cmd
  ::
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.cmd c:\mytemp\tmp$$$.vbs) do del %%f
  rmdir c:\mytemp
  ::
  :: Show the result
  echo %HexString%
  echo %AsciiString%
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  Dim MyHexString 'VBS
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  MyHexString=WshShell.ExpandEnvironmentStrings("%HexString%") 'VBS
  WScript.Echo "@set AsciiString=" & HexStringToAsciiString(MyHexString) 'VBS
  '
  Function HexStringToAsciiString(HexStr) 'VBS
    For i = 1 To Int(Len(HexStr)/3)+1 'VBS
      str1 = str1 & Chr("&H" & Mid(HexStr,3*i-2,2)) 'VBS
    Next 'VBS
    HexStringToAsciiString=str1 'VBS
  End Function 'VBS
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:14 2011
Subject: 74) How can I compare two numbers that have decimals with IF?
Date: Mon, 31 Jan 2011 01:01:14
From: ts@uwasa.fi (Timo Salmi)

A straight comparison of two decimal numbers will not work reliably,
since they are interpreted and compared as strings because the
decimal point makes the number in fact a string. Consider the
following code, which will _not_ produce wanted results.
  @echo off & setlocal enableextensions
  set number1=7.2
  set number2=-7.3
  ::
  :: Give the result
  if %number1% EQU %number2% (
    echo %number1% is equal to %number2%
    ) else (
    if %number1% GTR %number2% (
      echo %number1% is greater than %number2%
      ) else (
      echo %number1% is smaller than %number2%
    )
  )
  endlocal & goto :EOF
The output will, undesirably be
  D:\TEST>cmdfaq
  7.2 is smaller than -7.3

Instead, the following script will first convert the decimals into
integers for the comparison
  @echo off & setlocal enableextensions
  ::
  :: Get the numbers, one way or another
  if not [%2]==[] (
    set number1=%1
    set number2=%2
    ) else (
    echo Usage: %~f0 number1 number2
    endlocal & goto :EOF
    )
  ::
  :: See to it that the numbers have at least four decimal places
  call :Add4Decimals %number1% numb1
  call :Add4Decimals %number2% numb2
  ::
  :: Get the integer part and _exactly_ four decimals of the numbers
  call :ParseNumber %numb1% fix1 dec1
  call :ParseNumber %numb2% fix2 dec2
  ::
  :: Build up the numbers to be compared
  set /a n1=%fix1%%dec1%
  set /a n2=%fix2%%dec2%
  echo "Debugging" information: Comparing in fact
  echo %fix1%%dec1% and %fix2%%dec2%
  ::
  :: Give the result
  if %n1% EQU %n2% (
    echo %number1% is equal to %number2%
    ) else (
    if %n1% GTR %n2% (
      echo %number1% is greater than %number2%
      ) else (
      echo %number1% is smaller than %number2%
    )
  )
  endlocal & goto :EOF
  ::
  :: =============================================
  :Add4Decimals
  setlocal enableextensions enabledelayedexpansion
  echo %1|find ".">nul
  if %errorlevel% EQU 1 (
    endlocal& set %2=%1.0000&goto :EOF
    ) else (
    endlocal& set %2=%10000&goto :EOF)
  ::
  :: =============================================
  :ParseNumber
  setlocal enableextensions enabledelayedexpansion
  for /f "tokens=1,2 delims=." %%m in ('echo %1') do (
    set fix=%%m
    set dec=%%n)
  set dec=%dec:~0,4%
  endlocal& set %2=%fix%& set %3=%dec%& goto :EOF
The output will be
  D:\TEST>cmdfaq 7.2 -7.3
  "Debugging" information: Comparing in fact
  72000 and -73000
  7.2 is greater than -7.3

A Visual Basic Script (VBScript) aided command line script solution:
  @echo off & setlocal enableextensions
  ::
  :: Get the numbers, one way or another
  set number1=7.2
  set number2=-7.3
  ::
  :: Build a Visual Basic Script
  if not exist c:\mytemp mkdir "c:\mytemp"
  findstr "'%skip%VBS" "%~f0" > "c:\mytemp\tmp$$$.vbs"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "c:\mytemp\tmp$$$.vbs">"c:\mytemp\tmp$$$.cmd"
  ::
  :: Call the CMD.EXE script created by the above redirection
  call "c:\mytemp\tmp$$$.cmd"
  ::
  :: Show and interpret the results
  echo Testing: %number1% %number2% %sign%
  if %sign% EQU 0 (
    echo %number1% is equal to %number2%
    ) else (
    if %sign% EQU 1 (
      echo %number1% is greater than %number2%
      ) else (
      echo %number1% is smaller than %number2%
    )
  )
  ::
  :: Clean up
  for %%f in ("c:\mytemp\tmp$$$.vbs" "c:\mytemp\tmp$$$.cmd") do (
    if exist %%f del %%f)
  rmdir "c:\mytemp"
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  n1=WshShell.ExpandEnvironmentStrings("%number1%") 'VBS
  n2=WshShell.ExpandEnvironmentStrings("%number2%") 'VBS
  WScript.StdOut.WriteLine "@set sign=" & Sgn(n1-n2) 'VBS
The output will be
  D:\TEST>cmdfaq
  Testing: 7.2 -7.3 1
  7.2 is greater than -7.3

A G(nu)AWK aided solution
  @echo off & setlocal enableextensions
  ::
  :: Get the numbers, one way or another
  set number1=7.2
  set number2=-7.3
  ::
  :: Build a GnuAWK program file
  if not exist c:\mytemp mkdir c:\mytemp
  > c:\mytemp\tmp$$$.awk echo BEGIN{
  >>c:\mytemp\tmp$$$.awk echo if ^(^(%number1%^)-^(%number2%^)==0^) sgn=0
  >>c:\mytemp\tmp$$$.awk echo else if ^(index^(^(%number1%^)-^(%number2%^),"-"^)^) sgn=-1
  >>c:\mytemp\tmp$$$.awk echo else sgn=1
  >>c:\mytemp\tmp$$$.awk echo printf "@set sign=%%s\n",sgn
  >>c:\mytemp\tmp$$$.awk echo }
  ::
  :: Execute
  gawk -f c:\mytemp\tmp$$$.awk>c:\mytemp\tmp$$$.cmd
  call c:\mytemp\tmp$$$.cmd
  ::
  :: Show and interpret the results
  echo Testing: %number1% %number2% %sign%
  if %sign% EQU 0 (
    echo %number1% is equal to %number2%
    ) else (
    if %sign% EQU 1 (
      echo %number1% is greater than %number2%
      ) else (
      echo %number1% is smaller than %number2%
    )
  )
  ::
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.awk c:\mytemp\tmp$$$.cmd) do del %%f
  rmdir c:\mytemp
  endlocal & goto :EOF
The output will again be
  D:\TEST>cmdfaq
  Testing: 7.2 -7.3 1
  7.2 is greater than -7.3
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:15 2011
Subject: 75) How do I detect if an object is a file or a folder?
Date: Mon, 31 Jan 2011 01:01:15
From: ts@uwasa.fi (Timo Salmi)

A command-line script only solution based on a Usenet news posting
by Ted Davis
  @echo off & setlocal enableextensions
  if "%~1"=="" (set object=NoPara & goto _echo)
  if not exist "%~1" (
    set object=notfound
    ) else (
    set object=folder
    dir "%~1" | find "<DIR>" > nul
    if errorlevel 1 set object=file)
  :_echo
  echo The object is a %object%
  endlocal & goto :EOF

A more complicated Visual Basic Script (VBScript) aided command line
script solution:
  @echo off & setlocal enableextensions
  ::
  :: Get the nameobject to be checked
  set FName_=%~1
  if "%FName_%"=="" (
    echo.
    echo Usage: %~f0 FName
    goto :EOF
  )
  if not [%2]==[] (
    echo.
    echo Long file names must be in parentheses ^(^"^)
    goto :EOF
  )
  ::
  :: Test the traditional way to see that the difference between
  :: a file and a folder is not detected
  if not exist "%FName_%" (
    echo "%FName_%" not found
    ) else (
    echo "%FName_%" found)
  ::
  :: Build a Visual Basic Script
  if not exist c:\mytemp mkdir c:\mytemp
  findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo c:\mytemp\tmp$$$.vbs>c:\mytemp\tmp$$$.cmd
  ::
  :: Call the CMD script made my the VBS script
  call c:\mytemp\tmp$$$.cmd
  ::
  :: Show the results
  echo %FName_% %FNameStatus%
  ::
  :: Clean up
  for %%f in (c:\mytemp\tmp$$$.vbs c:\mytemp\tmp$$$.cmd) do del %%f
  rmdir c:\mytemp
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Dim FSO, f                                                     'VBS
  Set WshShell = WScript.CreateObject("WScript.shell")           'VBS
  FName=WshShell.ExpandEnvironmentStrings("%FName_%")            'VBS
  '                                                              'VBS
  Set FSO=CreateObject("Scripting.FileSystemObject")             'VBS
  If not (FSO.FileExists(FName) or FSO.FolderExists(FName)) Then 'VBS
    WScript.Echo "@set FNameStatus=NotFound"                     'VBS
    WScript.Quit                                                 'VBS
  End If                                                         'VBS
  If FSO.FileExists(FName) Then                                  'VBS
    Set f = FSO.GetFile(FName)                                   'VBS
  End if                                                         'VBS
  If FSO.FolderExists(FName) Then                                'VBS
    Set f = FSO.GetFolder(FName)                                 'VBS
  End if                                                         'VBS
  If (f.attributes and 16) Then                                  'VBS
    WScript.Echo "@set FNameStatus=Folder"                       'VBS
  Else                                                           'VBS
    WScript.Echo "@set FNameStatus=File"                         'VBS
  End If                                                         'VBS

However, maybe the simplest method is
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 [FileOrFolderName]
    goto :EOF
    )
  ::
  if not exist "%~1" (
    echo File or folder "%~1" not found
    goto :EOF
    )
  if exist "%~1\" (
    echo "%~1" is a folder
    ) else (
    echo "%~1" is a file
    )
  endlocal & goto :EOF

Formulated slightly differently:
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: "%~f0" ["File or foldername", no backslash \]
    goto :EOF)
  if not exist "%~1" echo "%~1" not found
  if exist "%~1" if not exist "%~1\" echo "%~1" is a file
  if exist "%~1\" echo "%~1" is a folder
  endlocal & goto :EOF

Another approach, for testing folder existence only
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 [FileOrFolderName]
    goto :EOF)
  dir /b /a:d "%~1" >nul 2>&1 &&(echo Folder found)||(echo Folder not found or is a file)
  endlocal & goto :EOF

Warning: As explained in the earlier Item #59 on post MS-DOS+Win../95/
98/Me systems it is not advisable to test for folder's existence with
  if exist "%~1\nul" echo "%~1" is a folder

References/Comments:
 http://www.google.com/groups?selm=c2uroi%24pvs%2406%241%40news.t-online.com
 http://www.google.com/groups?selm=O4huX7rRGHA.424%40TK2MSFTNGP12.phx.gbl
 http://www.google.com/groups?selm=ehQOtBsRGHA.5656%40TK2MSFTNGP11.phx.gbl
 http://www.google.com/groups?selm=1166068807.744364.293490%4073g2000cwn.googlegroups.com
 http://www.google.com/groups?selm=49224d22$0$20336$9b536df3%40news.fv.fi

Alternative (note, omits deleting the temporary vbs):
 http://www.jsifaq.com/SF/Tips/Tip.aspx?id=10229
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:16 2011
Subject: 76) How do I create an empty file? How can I detect the empty files?
Date: Mon, 31 Jan 2011 01:01:16
From: ts@uwasa.fi (Timo Salmi)

Creating an empty file:
  if not exist empty.txt copy nul empty.txt
or
  set /p=""<nul>empty.txt

Detecting empty files in a folder:
  @echo off & setlocal enableextensions
  for %%f in ("C:\_D\TEST\*.*") do (
    if %%~zf EQU 0 echo %%~tf %%~zf "%%~ff"
    )
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  09.06.2008 16:26 0 "C:\_D\TEST\empty.txt"

And throughout an entire drive
  @echo off & setlocal enableextensions
  for /f "tokens=*" %%f in ('dir /b/s/a-d d:\*.*') do (
    if %%~zf EQU 0 echo %%~tf %%~zf %%~ff
    )
  endlocal & goto :EOF

Of course one could easily test for any particular size or range of
sizes. For example, are there files that are at least a megabyte in
size?
  @echo off & setlocal enableextensions
  for /f "tokens=*" %%f in ('dir /b/s/a-d "c:\*.*"') do (
    if %%~zf GEQ 1048576 echo %%~tf %%~zf %%~ff)
  endlocal & goto :EOF

Finding empty folders is covered in item #57.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:17 2011
Subject: 77) How do I list the files in \All Users\Desktop in the short format?
Date: Mon, 31 Jan 2011 01:01:17
From: ts@uwasa.fi (Timo Salmi)


There is no immediate DIR switch to do that. A brief round-about way
is the one below. It omits directory entries, hidden and system files.
The date, size, and the short-format name of the files are given. It
is easily customized.

  @echo off & setlocal enableextensions
  for /f "tokens=*" %%f in (
    'dir "%ALLUSERSPROFILE%\Desktop\*.*" /a:-d-h-s/b/s') do (
      echo %%~tzsf)
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  06.11.2003 10:35 1647 C:\DOCUME~1\ALLUSE~1\Desktop\ACCESS~1.LNK
  10.02.2008 21:24 1929 C:\DOCUME~1\ALLUSE~1\Desktop\ADOBER~1.LNK
  12.03.2008 17:21 926 C:\DOCUME~1\ALLUSE~1\Desktop\EDITPA~1.LNK
  06.04.2008 13:23 2137 C:\DOCUME~1\ALLUSE~1\Desktop\iTunes.lnk
  31.05.2007 17:20 1608 C:\DOCUME~1\ALLUSE~1\Desktop\MOZILL~3.LNK
  13.06.2008 19:51 598 C:\DOCUME~1\ALLUSE~1\Desktop\Opera.lnk
  27.01.2006 17:48 1732 C:\DOCUME~1\ALLUSE~1\Desktop\POWERD~1.LNK
  21.03.2008 17:45 903 C:\DOCUME~1\ALLUSE~1\Desktop\REALPL~1.LNK
  28.01.2006 20:56 894 C:\DOCUME~1\ALLUSE~1\Desktop\SNAGIT~1.LNK
  28.01.2006 20:12 2065 C:\DOCUME~1\ALLUSE~1\Desktop\SSHSEC~2.LNK
  28.01.2006 20:12 1105 C:\DOCUME~1\ALLUSE~1\Desktop\SSHSEC~1.LNK
  02.12.2004 22:39 742 C:\DOCUME~1\ALLUSE~1\Desktop\WINZIP~1.LNK

A Visual Basic aided command-line script for a single file
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 ["LongFileName"]
    goto :EOF)
  ::
  :: Check for the file's existence
  set found_=
  if exist "%~1" if not exist "%~1\" set found_=true
  if not defined found_ (
    echo File "%~1" not found or is a folder
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  for /f %%a in ('cscript //nologo "%vbs_%" "%~1"') do set sfn_=%%a
  ::
  :: Display the results
  echo %~nx1
  echo %sfn_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  WScript.Echo GetShortName(WScript.Arguments.Item(0)) 'VBS
  '
  Function GetShortName(filespec) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFile(filespec) 'VBS
    GetShortName = f.ShortName 'VBS
  End Function 'VBS

The output could be e.g.
  C:\TEST>CMDFAQ.CMD "%ALLUSERSPROFILE%\Desktop\Adobe Reader 9.lnk"
  Adobe Reader 9.lnk
  ADOBER~1.LNK

A related question: In a folder with a long name how does one get its
short-format on the command line?
  for /f "tokens=*" %d in ("%cd%") do @echo %~sd

The output could be e.g.
  C:\Documents and Settings\All Users\Documents\My Pictures>for /f "tokens=*" %d in ("%cd%") do @echo %~sd
  C:\DOCUME~1\ALLUSE~1\DOCUME~1\MYPICT~1

A Visual Basic aided command-line script for the short name of a folder
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 ["LongFolderName"]
    goto :EOF)
  ::
  :: Check for the file's existence
  set found_=
  if not exist "%~1\" (
    echo Folder "%~1" not found
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  for /f %%a in ('cscript //nologo "%vbs_%" "%~1"') do set sfn_=%%a
  ::
  :: Display the resultsBR>   echo %~1
  echo %sfn_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  WScript.Echo GetShortPath(WScript.Arguments.Item(0)) 'VBS
  '
  Function GetShortPath(filespec) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(filespec) 'VBS
    GetShortPath = f.ShortPath 'VBS
  End Function 'VBS

The output could be e.g.
  C:\TEST>CMDFAQ.CMD "%ALLUSERSPROFILE%\Desktop"
  C:\Documents and Settings\All Users\Desktop
  C:\DOCUME~1\ALLUSE~1\Desktop

Returning VBS-aided to the original task "How do I list the files in
\All Users\Desktop in the short format?":
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  ::
  :: Browse through the target folder's files
  for /f "tokens=*" %%f in (
    'dir "%ALLUSERSPROFILE%\Desktop\*.*" /a:-d-h-s/b/s') do (
      call :DisplayTheShortPath "%%f")
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  :DisplayTheShortPath
  for /f %%a in ('cscript //nologo "%vbs_%" "%~1"') do echo %%a
  goto :EOF
  '
  'The Visual Basic Script
  WScript.Echo GetShortPath(WScript.Arguments.Item(0)) 'VBS
  '
  Function GetShortPath(pathspec) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFile(pathspec) 'VBS
    GetShortPath = f.ShortPath 'VBS
  End Function 'VBS

The output could be (on a different PC than the very first example) e.g.
  C:\TEST>CMDFAQ.CMD
  C:\DOCUME~1\ALLUSE~1\Desktop\ADOBER~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\AVIRAA~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\COMODO~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\EDITPA~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\HPSOLU~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\IRFANV~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\Opera.lnk
  C:\DOCUME~1\ALLUSE~1\Desktop\PDFCRE~1.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\PDFILL~2.LNK
  C:\DOCUME~1\ALLUSE~1\Desktop\Winamp.lnk

References/Comments:
  hh ntcmds.chm::/ntcmds_shelloverview.htm
  hh ntcmds.chm::/for.htm
  http://groups.google.fi/group/alt.msdos.batch.nt/msg/08446e03752f1f0d
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:18 2011
Subject: 78) Is it possible automatically to record my logon times into a file?
Date: Mon, 31 Jan 2011 01:01:18
From: ts@uwasa.fi (Timo Salmi)

This is reasonably simple. You'll need the following kind of a
script:
  @echo off & setlocal enableextensions
  echo Logon: %USERNAME% %COMPUTERNAME% %date% %time%>>C:\wherever\logon.txt
  endlocal & goto :EOF
Then
 Right-click the "start" in the lower left corner
  Choose "Explore"
   Choose the "Programs" folder
    Choose the "Startup" forlder. Create if need be.
     Click "File" in the upper left toolbar
      Click "New"
       Click "Shortcut"
        In the Wizard browse to your script
That's it. Next time you reboot, there will be an entry in your log.

If you wish to reverse the timeline, that is to have the lastest
entry on top, then e.g.
  @echo off & setlocal enableextensions
  if not defined temp goto :EOF
  echo Logon: %USERNAME% %COMPUTERNAME% %date% %time%>"%temp%\logon1.tmp"
  set target_=C:\logon.txt
  if not exist "%target_%" (
    copy /y "%temp%\logon1.tmp" "%target_%" > nul
    goto _out
    )
  copy "%target_%" "%temp%\logon2.tmp" > nul
  copy /y "%temp%\logon1.tmp" + "%temp%\logon2.tmp" "%target_%" > nul
  :_out
  for %%f in ("%temp%\logon1.tmp" "%temp%\logon2.tmp") do if exist %%f del %%f
  endlocal & goto :EOF
Customize the destination of the log file C:\logon.txt if you do not
have write permissions to the root directory of drive C:.
The logon.txt file might look someting like
 Logon: ts GARFIELD 26.10.2004 10:36:11.13
 Logon: ts GARFIELD 25.10.2004  8:33:36.79
 Logon: ts GARFIELD 24.10.2004  9:12:31.65

A sideline. The above assumes that there are no spaces in the %temp%
path. It is customary to use the 8+3 format for the temp variable to
avoid complications with spaces. E.g. one might have temp as
 C:\DOCUME~1\user\LOCALS~1\Temp
See item #39 for an example.

Incidentally, how does one permanently set an environment variable
value in XP?
 Right click: My Computer
 Choose Properties
 Choose Advanced
 Click "Environment Variables"
 For User variables click New
 Define Variable Value

What likewise about logout? See item #71. Just add
  echo Logout: %USERNAME% %COMPUTERNAME% %date% %time%>>C:\wherever\logon.txt
before the shutdown line.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:19 2011
Subject: 79) How can I trim leading and trailing spaces?
Date: Mon, 31 Jan 2011 01:01:19
From: ts@uwasa.fi (Timo Salmi)

If it is about a file, here is a demonstration
  @echo off & setlocal enableextensions
  :: Make and display a temporary test file
  echo  This  is  a  test   >MyTest.txt
  echo    Second  line     >>MyTest.txt
  echo.>>MyTest.txt
  echo    Fourth  line     >>MyTest.txt
  type Mytest.txt
  :: Trim
  <Mytest.txt sed -e "s/^ *//" -e "s/ *\.$//"
  :: Clean up
  del Mytest.txt
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  Thisisatest
  Secondline
  
  Fourthline
  This  is  a  test
  Second  line

  Fourth  line

Or, with a pure script, provided there are no backslashes (\)
  @echo off & setlocal enableextensions enabledelayedexpansion
  set debug=X
  :: Make a temporary test file
  echo  This  is  a  test   >MyTest.txt
  echo    Second  line     >>MyTest.txt
  echo.>>MyTest.txt
  echo    Fourth  line     >>MyTest.txt
  :: Trim
  for /f "tokens=* delims= " %%a in ('type Mytest.txt') do (
    set s_=%%~na
    echo !s_!%debug%
    )
  :: Clean up
  del Mytest.txt
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  This  is  a  testX
  Second  lineX
  X
  Fourth  lineX

The latter option is not without problems. Note what happens if we
substitute set debug=
The output will be
  D:\TEST>cmdfaq
  This  is  a  test
  Second  line
  ECHO is off.
  Fourth  line

But let's move on. If it is about an environment variable:
  @echo off & setlocal enableextensions
  set S=  This  is  a  test
  echo %S%.
  echo %S%|sed -e "s/^ *//" -e "s/ *$//" -e "s/^/@set S=&/">"%temp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  echo %S%.
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
    This  is  a  test     .
  This  is  a  test.

The problem can also be solved with a Visual Basic Script (VBScript)
  @echo off & setlocal enableextensions
  set S=  This  is  a  test
  echo %S%.
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Trim("%S%")
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%temp%\tmp$$$.vbs"') do set S=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  echo %S%.
  endlocal & goto :EOF

The output will again be
  D:\TEST>cmdfaq
    This  is  a  test     .
  This  is  a  test.

Or, with a pure script
  @echo off & setlocal enableextensions
  rem enabledelayedexpansion
  set S=  This  is  a  test
  echo %S%.
  for /f "tokens=* delims= " %%a in ('echo %S%') do set S=%%a
  echo %S%.
  endlocal & goto :EOF

Note, however, that the output will be a different:
  D:\TEST>cmdfaq
    This  is  a  test     .
  This is a test .

Likewise, one can drop the _leading_ zeros:
  @echo off & setlocal enableextensions
  set num=0800
  for /f "tokens=* delims=0" %%a in ('echo %num%') do set num=%%a
  echo %num%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  800

How can I trim trailing spaces from a file?

First write the following Visual Basic Script file calling it RTRIMMER.VBS
  Do While Not WScript.StdIn.AtEndOfStream
    WScript.Echo RTrim(WScript.StdIn.ReadLine)
  Loop
Then apply
  cscript //nologo TRIMMER.VBS < "My Old Text File.txt" > "My New Text File.txt"
For trimming leading spaces use LTRIM and for applying both use TRIM.

Another solution is
  <"My Old Text File.txt" sed -e "s/ *$//" >"My New Text File.txt"

References/Comments:
 http://www.google.com/groups?selm=26D08E3E-0C2D-4E38-84BA-7E9B37651B76%40microsoft.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:20 2011
Subject: 80) How can I extract the last part of a path such as C:\ABC\DEF\GHI\?
Date: Mon, 31 Jan 2011 01:01:20
From: ts@uwasa.fi (Timo Salmi)

The core of question as posed on the Usenet news is how processing
  >"C:\ABX\XYZ\"     would return "XYZ"
  >"C:\ABC\DEF\GHI " would return "GHI"
  >"C:\ABC\DEF\GHI\" would return "GHI"

There are several solutions. First with SED and GAWK. But before
reading on, you may wish to revisit the previous item #79 on trimming.
Also see a later item #115 on decomposing the path to be one folder
per line.
  @echo off & setlocal enableextensions
  set mystr=C:\ABC\DEF XYZ\GHI\
  echo %mystr%|sed -e "s/\\*$//"^
    |gawk -F\ '{printf "@set last=%%s\n",$NF}'^
    >"%temp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  echo %mystr%
  echo %last%
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  C:\ABC\DEF XYZ\GHI\
  GHI

Observations on the above. The sed -e "s/\\*$//" sees to it that there
are no trailing backslashes (\). The first backslash \, however, is an
escape character for sed which is needed to take the second \
literally. The above also uses another escape character, the caret ^
to continue a CLI script command on the next line.

Next let's take a step by step enhancements as often happens with
questions that have arisen when a discussion has continued on the
Usenet news about a particular problem.

Second solution, with pure script in a slow, generic fashion.
  @echo off & setlocal enableextensions enabledelayedexpansion
  set mystr=C:\ABC\DEF XYZ\GHI\
  echo %mystr%
  :: Remove the last character
  set mystr=%mystr:~0,-1%
  echo %mystr%
  :: Get the position of the last \
  call :InstrLastFN "%mystr%" "\\" pos
  set /a pos +=1
  :: Get the desired substring
  set result=!mystr:~%pos%!
  rem echo %result%
  for %%a in ("%mystr%") do echo %%~na
  endlocal & goto :EOF
  ::
  :: ============================================================
  :InstrLastFN
  setlocal enableextensions enabledelayedexpansion
  echo %1|findstr %2>nul
  if %errorlevel% EQU 1 (endlocal & set %3=-1& goto :EOF)
  set rest_=%1
  set /a instr_=-1
  :_loop
    set rest_=%rest_:~1%
    echo !rest_!|findstr %2>nul
    if %errorlevel% EQU 1 (endlocal & set %3=%instr_%& goto :EOF)
    set /a instr_ +=1
    goto _loop
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  C:\ABC\DEF XYZ\GHI\
  C:\ABC\DEF XYZ\GHI
  GHI

The neatest solution is adapted from a posting by Phil Robyn.
  @echo off & setlocal enableextensions enabledelayedexpansion
  set mystr=C:\ABC\DEF XYZ\GHI\
  echo %mystr%
  set mystr=%mystr:~0,-1%
  echo %mystr%
  for %%a in ("%mystr%") do echo %%~na
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  C:\ABC\DEF XYZ\GHI\
  C:\ABC\DEF XYZ\GHI
  GHI

Even that solution can be enhanced as pointed out on the Usenet
news. The first trick (%%~fa) is to ensure that a potential trailing
\ is removed without disturbing the string if the \ is not there.
The second trick (%%~nxa) is ensuring that a critically placed,
potential dot (.) in the string is not dropped. See the References
for more, and the originators.
  @echo off & setlocal enableextensions
  set debug=true
  set mystr=C:\ABC\DEF XYZ\.GHI\
  for %%a in ("%mystr%\") do set mystr=%%~fa
  if defined debug echo %mystr%
  set mystr=%mystr:~0,-1%
  if defined debug echo %mystr%
  for %%a in ("%mystr%") do set mystr=%%~nxa
  if defined debug echo %mystr%
  endlocal & goto :EOF
The output will be
  D:\TEST>cmdfaq
  C:\ABC\DEF XYZ\.GHI\
  C:\ABC\DEF XYZ\.GHI
  .GHI
In the old days when the proverbial "we" programmed in straight
MS-DOS batch we relied a lot on the peculiarities of the DOS batch
syntax. When the versions changed, some of the tricks no longer
worked. The above has some resemblance in the sense that it assumes
that the %~fa trick will stay. A nice and an inventive solution,
nevertheless.

A more generic option to handle the trailing bakcslash \ is
  @echo off & setlocal enableextensions
  set debug=true
  set mystr=C:\ABC\\DEF XYZ\.GHI\
  if defined debug echo %mystr%
  set mystr=%mystr%\
  if defined debug echo %mystr%
  set mystr=%mystr:\\=\%
  if defined debug echo %mystr%
  set mystr=%mystr:~0,-1%
  if defined debug echo %mystr%
  for %%a in ("%mystr%") do set mystr=%%~nxa
  if defined debug echo %mystr%
  endlocal & goto :EOF
producing the following output
  D:\TEST>cmdfaq
  C:\ABC\\DEF XYZ\.GHI\
  C:\ABC\\DEF XYZ\.GHI\\
  C:\ABC\DEF XYZ\.GHI\
  C:\ABC\DEF XYZ\.GHI
  .GHI

Another demonstration
  @echo off & setlocal enableextensions disabledelayedexpansion
  :: Get the string to be parsed
  set MyArguments=%~1
  if "%~1"=="" set MyArguments=d:\folder 1\folder 2\folder 3\
  echo MyArguments=%MyArguments%
  ::
  :: Get the first part and the rest of a variable
  for /f "tokens=1,* delims=\" %%a in ("%MyArguments%") do (
    set first_=%%a
    set rest_=%%b
    )
  echo first_=%first_%
  echo rest_ =%rest_%
  ::
  :: Get the last part of a variable
  set rest_=%MyArguments%
  :_loop
  for /f "tokens=1,* delims=\" %%a in ("%rest_%") do (
    set rest_=%%b
    set last_=%%a
    if defined rest_ goto _loop
    )
  echo last_=%last_%
  endlocal & goto :EOF

The output:
  C:\_D\TEST>cmdfaq
  MyArguments=d:\folder 1\folder 2\folder 3\
  first_=d:
  rest_ =folder 1\folder 2\folder 3\
  last_=folder 3

Also see the item
 144} How do I parse the items from a path like C:\a\b\c\d ?

References/Comments:
 http://www.google.com/groups?selm=1104461083.217256.292420%40z14g2000cwz.googlegroups.com
 http://www.google.com/groups?selm=cr277b%24gg8%2400%241%40news.t-online.com
 http://www.google.com/groups?selm=NJkBd.657015%24%k.480801%40pd7tw2no
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:21 2011
Subject: 81) Is there a script to capitalize all the words in a text file?
Date: Mon, 31 Jan 2011 01:01:21
From: ts@uwasa.fi (Timo Salmi)

 Q: "I need a batch file that will change the first letter in every
word in a text file to upper case."

 A: Using sed
  @echo off & setlocal enableextensions
  if not defined mytemp set mytemp=%temp%
  set sedcmd="%mytemp%\sedcmd.tmp"
  >  %sedcmd% echo s/ a/ A/g
  >> %sedcmd% echo s/ b/ B/g
  >> %sedcmd% echo s/ c/ C/g
  >> %sedcmd% echo s/ d/ D/g
  >> %sedcmd% echo s/ e/ E/g
  >> %sedcmd% echo s/ f/ F/g
  >> %sedcmd% echo s/ g/ G/g
  >> %sedcmd% echo s/ h/ H/g
  >> %sedcmd% echo s/ i/ I/g
  >> %sedcmd% echo s/ j/ J/g
  >> %sedcmd% echo s/ k/ K/g
  >> %sedcmd% echo s/ l/ L/g
  >> %sedcmd% echo s/ m/ M/g
  >> %sedcmd% echo s/ n/ N/g
  >> %sedcmd% echo s/ o/ O/g
  >> %sedcmd% echo s/ p/ P/g
  >> %sedcmd% echo s/ q/ Q/g
  >> %sedcmd% echo s/ r/ R/g
  >> %sedcmd% echo s/ s/ S/g
  >> %sedcmd% echo s/ t/ T/g
  >> %sedcmd% echo s/ u/ U/g
  >> %sedcmd% echo s/ v/ V/g
  >> %sedcmd% echo s/ w/ W/g
  >> %sedcmd% echo s/ x/ X/g
  >> %sedcmd% echo s/ y/ Y/g
  >> %sedcmd% echo s/ z/ Z/g
  rem
  >> %sedcmd% echo s/^^a/A/g
  >> %sedcmd% echo s/^^b/B/g
  >> %sedcmd% echo s/^^c/C/g
  >> %sedcmd% echo s/^^d/D/g
  >> %sedcmd% echo s/^^e/E/g
  >> %sedcmd% echo s/^^f/F/g
  >> %sedcmd% echo s/^^g/G/g
  >> %sedcmd% echo s/^^h/H/g
  >> %sedcmd% echo s/^^i/I/g
  >> %sedcmd% echo s/^^j/J/g
  >> %sedcmd% echo s/^^k/K/g
  >> %sedcmd% echo s/^^l/L/g
  >> %sedcmd% echo s/^^m/M/g
  >> %sedcmd% echo s/^^n/N/g
  >> %sedcmd% echo s/^^o/O/g
  >> %sedcmd% echo s/^^p/P/g
  >> %sedcmd% echo s/^^q/Q/g
  >> %sedcmd% echo s/^^r/R/g
  >> %sedcmd% echo s/^^s/S/g
  >> %sedcmd% echo s/^^t/T/g
  >> %sedcmd% echo s/^^u/U/g
  >> %sedcmd% echo s/^^v/V/g
  >> %sedcmd% echo s/^^w/W/g
  >> %sedcmd% echo s/^^x/X/g
  >> %sedcmd% echo s/^^y/Y/g
  >> %sedcmd% echo s/^^z/Z/g
  rem
  sed -f%sedcmd% < "My test file.txt"
  for %%f in (%sedcmd%) do if exist del %%f
  endlocal & goto :EOF

Assume the following LFN-type test file: "My test file.txt"
  line 1
  line 2 &()[]{}^=;!'+,`~
  line 3 <>

  
  06
  line 7 Line "4" is blank, "5" and "6" are short!
  line 8
  line 9 &()[]{}^=;!'+,`~ ends it

The output will be
  C:\_D\TEST>cmdfaq
  Line 1
  Line 2 &()[]{}^=;!'+,`~
  Line 3 <>

  
  06
  Line 7 Line "4" Is Blank, "5" And "6" Are Short!
  Line 8
  Line 9 &()[]{}^=;!'+,`~ Ends It

What about foreign character sets? For example for the Finnish
character set add
  >> %sedcmd% echo s/ / /g
  >> %sedcmd% echo s/ / /g
  >> %sedcmd% echo s/ / /g
  rem
  >> %sedcmd% echo s/^^//g
  >> %sedcmd% echo s/^^//g
  >> %sedcmd% echo s/^^//g

Of course, one could emulate the above with a pure script, to a
degree, or with a Visual Basic Script (VBScript) aided command line
script. However, the task is so much better suited for the
specialized SED stream editor that the alternatives are left to the
gentle reader as an exercise. If you are interested, take additional
cues from item #39.

References/Comments:
 http://www.google.com/groups?selm=41ea366b%241_2%40127.0.0.1
 http://www.google.com/groups?selm=64alu0h1rgs0csc3sa3kd737upcnve1h2m%404ax.com
 http://www.google.com/groups?selm=YSPaoRH8cq6BFwM1%40merlyn.demon.co.uk
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:22 2011
Subject: 82) Why does echo 9>temp.txt fail while echo 10>temp.txt works?
Date: Mon, 31 Jan 2011 01:01:22
From: ts@uwasa.fi (Timo Salmi)

A cmd.exe feature. The sole digit nine is taken to be a file handle
0-9 when redirection is used. You'll have to escape it e.g. applying
  @echo off
  echo ^9>temp.txt
or
  echo.9>temp.txt
or
  >temp.txt echo 9
or
  (echo 9)>temp.txt

The problem might be particularly insidious in a case like this
  @echo off & setlocal enableextensions
  set var_=9
  echo %var_%>tmp$$$.txt
  for %%c in (type del) do call %%c tmp$$$.txt
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  ECHO is off.
That can be avoided by using
  echo ^%var_%>tmp$$$.txt
or
  echo.%var_%>tmp$$$.txt
or
  >tmp$$$.txt echo %var_%
or
  (echo %var_%)>tmp$$$.txt

What does one do with a file handle? Try this without having a
diskette in the drive
  @echo off
  dir a: > temp.dir
What you'll get is on the screen
  The device is not ready.
But if you would rather that the line went into the temp.dir file,
then
  @echo off
  dir a:> temp.dir 2>&1

References/Comments:
 http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/redirection.mspx?mfr=true
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:23 2011
Subject: 83) How to archive files with a rotation of five latest generations?
Date: Mon, 31 Jan 2011 01:01:23
From: ts@uwasa.fi (Timo Salmi)

> I would like to archive some files periodically but only keep the last
> five iterations. The directories would ideally have date names. I know
> how to get a date into a directory name but I'm having a bit of trouble
> trying to figure out how to delete the oldest directory.

Such a backup rotation uses moves or renames. Below is the logic. The
commands (e.g. zipping or whatever) are easily written once the simple
logic sinks in:
 archive4 --> archive5
 archive3 --> archive4
 archive2 --> archive3
 archive1 --> archive2
 delete archive1
 Do the new archiving to archive1

References/Comments:
 http://www.google.com/groups?selm=483269c6$0$8054$a82e2bb9%40reader.athenanews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:24 2011
Subject: 84) How can I automate downloading files from an ftp-site?
Date: Mon, 31 Jan 2011 01:01:24
From: ts@uwasa.fi (Timo Salmi)

This example will get you the following files from the Garbo program
archives at the University of Vaasa, Finland
ftp://garbo.uwasa.fi/pc/link/tsbat.zip
ftp://garbo.uwasa.fi/pc/link/tscmd.zip

  @echo off & setlocal enableextensions
  echo open garbo.uwasa.fi>"%temp%\ftp$$$.tmp"
  echo anonymous>>"%temp%\ftp$$$.tmp"
  echo myid@mypc.mydomain>>"%temp%\ftp$$$.tmp"
  echo binary>>"%temp%\ftp$$$.tmp"
  echo cd /pc/link>>"%temp%\ftp$$$.tmp"
  echo literal pasv>>"%temp%\ftp$$$.tmp"
  echo lcd C:\_MyLocalDownloadsFolder>>"%temp%\ftp$$$.tmp"
  echo get tsbat.zip>>"%temp%\ftp$$$.tmp"
  echo get tscmd.zip>>"%temp%\ftp$$$.tmp"
  echo quit>>"%temp%\ftp$$$.tmp"
  ftp -s:"%temp%\ftp$$$.tmp"
  del "%temp%\ftp$$$.tmp"
  endlocal & goto :EOF

Or, written slightly differently for better clarity
  @echo off & setlocal enableextensions
  set scr_=%temp%\ftp$$$.tmp
  > "%scr_%" echo open garbo.uwasa.fi
  >>"%scr_%" echo anonymous
  >>"%scr_%" echo myid@mypc.mydomain
  >>"%scr_%" echo binary
  >>"%scr_%" echo cd /pc/link
  >>"%scr_%" echo literal pasv
  >>"%scr_%" echo lcd C:\_M
  >>"%scr_%" echo get tsbat.zip
  >>"%scr_%" echo get tscmd.zip
  >>"%scr_%" echo quit
  ftp -s:"%scr_%"
  del "%scr_%"
  endlocal & goto :EOF

The clearest option, however, probably is
  @echo off & setlocal enableextensions
  set scr_=%temp%\ftp$$$.tmp
  (
    echo open garbo.uwasa.fi
    echo anonymous
    echo myid@mypc.mydomain
    echo binary
    echo cd /pc/link
    echo literal pasv
    echo lcd C:\_M
    echo get tsbat.zip
    echo get tscmd.zip
    echo quit
  )>"%scr_%"
  ftp -s:"%scr_%"
  del "%scr_%"
  endlocal & goto :EOF

One might get e.g.
  C:\_D\TEST>dir C:\_M\*.ZIP |find /i "zip"
  22.05.2008  23:27           254,761 tsbat.zip
  22.05.2008  23:27           223,203 tscmd.zip

If you need to include sensitive user and password information into
the script, see Item #182.

Another question from the Usenet news:
> ftp client in Windows can show me the DIR of a[n] ftp folder.
> Switching to FTP mode by typing FTP in the dosbox
> Under FTP, a "dir >C:\dir.txt" does not work for me.
> How can i send that output to a txt File?
> I want to get the directory listing into a textfile.

An example of getting the listing of Garbo's /pc/ts directory using
generic logging
  @echo off & setlocal enableextensions
  set scr_=%temp%\ftp$$$.tmp
  set log_=%temp%\ftp.log
  > "%scr_%" echo verbose
  >>"%scr_%" echo open garbo.uwasa.fi
  >>"%scr_%" echo anonymous
  >>"%scr_%" echo myid@mypc.mydomain
  >>"%scr_%" echo cd /pc/ts
  >>"%scr_%" echo verbose
  >>"%scr_%" echo ls -lF
  >>"%scr_%" echo verbose
  >>"%scr_%" echo quit
  ftp -s:"%scr_%">"%log_%"
  type "%log_%"
  for %%f in ("%scr_%" "%log_%") do if exist %%f del %%f
  endlocal & goto :EOF
If you wish to keep the directory listing, naturally don't delete the %
log_% file.

What is in the above is based on general FTP logging. However, if you
indeed wish to store the directory listing in particular, then
  @echo off & setlocal enableextensions
  set scr_=%temp%\ftp$$$.tmp
  set log_=%temp%\ftptsdir.log
  > "%scr_%" echo verbose
  >>"%scr_%" echo open garbo.uwasa.fi
  >>"%scr_%" echo anonymous
  >>"%scr_%" echo myid@mypc.mydomain
  >>"%scr_%" echo dir /pc/ts "%log_%"
  >>"%scr_%" echo quit
  ftp -s:"%scr_%"
  more "%log_%"
  for %%f in ("%scr_%" "%log_%") do if exist %%f del %%f
  endlocal & goto :EOF

> How do I just test if a file exists on on FTP site?
All the ingredients have more or less already been covered here, but
below is nevertheless an example.
  @echo off & setlocal enableextensions
  ::
  :: Set some environment variables
  set scr_=%temp%\ftp$$$.tmp
  set log_=%temp%\ftpdir.log
  set find_=tscmd.zip
  ::
  :: Build and send the FTP commands
  (
    echo open garbo.uwasa.fi
    echo anonymous
    echo myid@mypc.mydomain
    echo cd /pc/link
    echo ls . "%log_%"
    echo quit
  )>"%scr_%"
  ftp -s:"%scr_%" > nul
  ::
  :: Was the log created?
  if not exist "%log_%" (
    echo The connection has probably failed
    goto _cleanup)
  ::
  :: Check the outcome
  find "%find_%" "%log_%" > nul
  if %errorlevel% EQU 0 (
    echo Found file "%find_%" on the FTP site
    ) else (
    echo File "%find_%" not found on the FTP site)
  ::
  :: Clean up
  :_cleanup
  for %%f in ("%scr_%" "%log_%") do if exist %%f del %%f
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=gg9t5r$fbl$00$1%40news.t-online.com
 http://groups.google.com/group/microsoft.public.win2000.cmdprompt.admin/msg/0514aac23054b37a
 http://support.microsoft.com/kb/96269/en-us
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:25 2011
Subject: 85) How to test if a folder contains any files with long names?
Date: Mon, 31 Jan 2011 01:01:25
From: ts@uwasa.fi (Timo Salmi)

What is a long file name (LFN)? To a degree a misnomer. Best defined
as a complement of the old MS-DOS file name, that is the familiar 8+3
and no spaces. Two main testing possibilities arise. Using the said
complement definition. Or using the fact that in Microsoft's usage the
long and the short file name (SFN) will differ.

The solutions below are based on the format of DIR /X /A:-D listing.
(The /A:-D means that the subfolders and thier names are not to be
tested.) E.g. one might have

C:\_M>DIR /X /A:-D
 Volume in drive C is WHATEVER
 Volume Serial Number is 61C1-66A2

 Directory of C:\_M

13.06.2008  16:19               496              CMDFAQ.CMD
13.06.2008  16:20                18 LONGNA~1.TXT LongNameFile.txt
13.06.2008  16:21                13 TEST2~1.CMD  test 2.cmd
13.06.2008  16:21                11              test.cmd
               4 File(s)            538 bytes
               0 Dir(s)  230,906,830,848 bytes free

The first solution option is based on the fact that if DIR /X is used
to get a folder listing the results will differ from the plain DIR
listing if there are long file names. Else, no difference, but in the
spacing.
  @echo off & setlocal enableextensions
  set dir1_=c:\_m\dirtmp1.txt
  set dirx_=c:\_m\dirtmpx.txt
  ::
  if "%~1"=="" (echo Usage [FolderName]&goto :EOF)
  ::
  dir "%~1" /a:-d /-c > "%dir1_%
  dir "%~1" /x /a:-d /-c > "%dirx_%
  ::
  fc /w "%dir1_%" "%dirx_%" > nul
  if %errorlevel% EQU 0 (
    echo No long file names found in "%~1"
    ) else (
    echo Long file names found in "%~1")
  ::
  for %%f in ("%dir1_%" "%dirx%") do if exist %%f del %%f
  endlocal & goto :EOF
The output could be e.g.
  C:\_M>cmdfaq C:\_M
  Long file names found in "C:\_M"

The second option is based on the following fact. For a long file name
the relevant row contains at least five space delimited items while
the other lines only have four. Furthermore, the folder listing's
footer must be dropped.
  @echo off & setlocal enableextensions
  set lfn_=
  for /f "skip=4 tokens=4-5 delims= " %%a in (
    'dir /x /a:-d /-c "%~1" ^|findstr /v /b /c:"  "') do (
    if not [%%b]==[] if /i not [%%a]==[%%b] set lfn_=true)
  if [%lfn_%]==[] (
    echo No long file names found in folder %1
     ) else (
    echo Long file names found in folder %1)
  endlocal & goto :EOF

For more information you may wish to take a look at
 dir /?
 findstr /?|more

The method can also be used to detect the LFN-status of a single
file:
  @echo off & setlocal enableextensions
  ::
  if [%1]==[] (
    echo Usage: %~0 [FileName]
    goto :EOF)
  ::
  echo %1|findstr "[*?]">nul
  if %errorlevel% EQU 0 (
    echo %1 contains wildcards, not allowed
    goto :EOF)
  ::
  if not exist "%~1" (
    echo File %1 not found
    goto :EOF)
  ::
  dir /a:d "%~1" 2>&1 |findstr /c:"<DIR>">nul
  if %errorlevel% EQU 0 (
    echo %1 is a folder
    goto :EOF)
  ::
  set lfn_=
  for /f "skip=4 tokens=4-5 delims= " %%a in (
    'dir /x /a:-d /-c "%~1" ^|findstr /v /b /c:"  "') do (
    if not [%%b]==[] if /i not [%%a]==[%%b] set lfn_=true)
  if [%lfn_%]==[] (
    echo %1 is not a long file name
     ) ELSE (
    echo %1 is a long file name)
  endlocal & goto :EOF

There are other methods. First consider the task of getting the
short format of a single filename
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%f in ("%~1") do (
    set lfn=%%~ff
    set sfn=%%~sf
    if not exist "!lfn!" (
      echo File "!lfn!" not found
      ) else (
      echo !lfn!
      echo !sfn!
      )
    )
  endlocal & goto :EOF
Note, however, that this method will fail if there are exclamation
marks (!) in the file name.

The output might be e.g.
  C:\_D\TEST>cmdfaq "C:\_M\test 2.txt"
  C:\_M\test 2.txt
  C:\_M\TEST2~1.TXT

Drawing from the above we could have
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  if "%~1"=="" (
    echo Usage %~0 [FolderName]
    goto :EOF
    )
  ::
  if not exist "%~1\" (
    echo Folder "%~1\" not found
    goto :EOF
    )
  ::
  set lfnFound=
  for %%f in ("%~1\*.*") do (
    set lfn=%%~ff
    set sfn=%%~sf
    if /i not "!lfn!"=="!sfn!" set lfnFound=true
    )
  ::
  if defined lfnFound (
    echo Long file names found in folder "%~1"
     ) ELSE (
    echo No long file names found in folder "%~1")
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq C:\_D\TEST
  Long file names found in folder "C:\_D\TEST"

Of course one could start from the definition of the long file name,
but this solution does not tolerate the poison charaters.
  @echo off & setlocal enableextensions
  set lfn_=
  set base_=%~n1
  set exte_=%~x1
  if not "%base_:~8%"=="" set lfn_=true
  if not "%exte_:~4%"=="" set lfn_=true
  echo %~nx1|find " ">nul
  if %errorlevel% EQU 0 set lfn_=true
  echo "%~1"
  if defined lfn_ echo is a long file name
  if not defined lfn_ echo is not a long file name
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=4263b31d%241_4%40alt.athenanews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:26 2011
Subject: 86) How to put each line of a text file into an environment variable?
Date: Mon, 31 Jan 2011 01:01:26
From: ts@uwasa.fi (Timo Salmi)

Assume the following LFN-type test file: "My test file.txt"
line 1
line 2
line 3

5
06
line 7 Line "4" is blank, "5" and "6" are short!
line 8
line 9 ends it

Note the use of the delayed expansion method
  @echo off & setlocal enableextensions enabledelayedexpansion
  set myfile_=C:\_D\TEST\My test file.txt
  for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
  ::
  :: Do it
  set lineNro_=
  for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
    set /a lineNro_+=1
    echo @set line!lineNro_!_=%%r>>"%temp%\tmp$$$.cmd"
    )
  :: Call the prepared auxiliary script and clean up
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  ::
  :: Display the outcome
  for /L %%v in (1,1,%lineNro_%) do echo line%%v_=!line%%v_!
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line1_=line 1
  line2_=line 2
  line3_=line 3
  line4_=5
  line5_=06
  line6_=line 7 Line "4" is blank, "5" and "6" are short
  line7_=line 8
  line8_=line 9 ends it
Observe that the empty line (the true fifth line) was skipped, and
that the exclamation mark ! does not appear because of the enabled
delayedexpansion. Also note that it is advisable that the text file
not contain the special script characters &()[]{}^=;!'+,`~

Actually, employing the intermediate script file %temp%\tmp$$$.cmd is
not necessary:
  @echo off & setlocal enableextensions enabledelayedexpansion
  set myfile_=C:\_D\TEST\My test file.txt
  ::
  :: Do it
  set lineNro_=
  for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
    set /a lineNro_+=1
    set line!lineNro_!_=%%r)
  ::
  :: Display the outcome and clean up
  for /L %%v in (1,1,%lineNro_%) do echo line%%v_=!line%%v_!
  endlocal & goto :EOF

How about without the delayed expansion? First consider
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Make a test file
  set myfile_=C:\_D\TEST\My test file2.txt
  for %%f in ("%myfile_%") do if exist %%f del %%f
  for %%f in (first! second third fourth) do (
    echo This is the %%f line>>"%myfile_%")
  echo.>>"%myfile_%"
  for %%f in (sixth seventh eight ninth tenth eleventh) do (
    echo This is the %%f line>>"%myfile_%")
  ::
  for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
  ::
  :: Do it
  set lineNro_=
  for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
    call :ProcessOneLine %%r)
  call "%temp%\tmp$$$.cmd"
  ::
  :: Display the outcome
  for /L %%v in (1,1,%lineNro_%) do (
    call echo line%%v_=%%line%%v_%%
    )
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.cmd" "%myfile_%") do (
    if exist %%f del %%f)
  endlocal & goto :EOF
  ::
  :ProcessOneLine
  set /a lineNro_+=1
  set row=%*
  echo @set line%lineNro_%_=%row%>>"%temp%\tmp$$$.cmd"
  goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  line1_=This is the first! line
  line2_=This is the second line
  line3_=This is the third line
  line4_=This is the fourth line
  line5_=This is the sixth line
  line6_=This is the seventh line
  line7_=This is the eight line
  line8_=This is the ninth line
  line9_=This is the tenth line
  line10_=This is the eleventh line

The empty line is dropped. But in all the results are as expected,
including the exlamation mark on the first line. However, let's alter
the test file a bit so that the contents of the test file will be

This is line 1!
This is line 2
This is line 3
This is line 4

This is line 6
This is line 7
This is line 8
This is line 9
This is line 10
This is line 11

  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  set myfile_=C:\_D\TEST\My test file2.txt
  for %%f in ("%myfile_%") do if exist %%f del %%f
  for %%f in (1! 2 3 4) do (
    echo This is line %%f>>"%myfile_%")
  echo.>>"%myfile_%"
  for %%f in (6 7 8 9 10 11) do (
    echo This is line %%f>>"%myfile_%")
  ::
  for %%f in ("%temp%\tmp$$$.cmd") do if exist %%f del %%f
  ::
  :: Do it
  set lineNro_=
  for /f "tokens=* delims=" %%r in ('type "%myfile_%"') do (
    call :ProcessOneLine %%r)
  call "%temp%\tmp$$$.cmd"
  ::
  :: Display the outcome
  for /L %%v in (1,1,%lineNro_%) do (
    call echo line%%v_=%%line%%v_%%
    )
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.cmd" "%myfile_%") do (
    if exist %%f del %%f)
  endlocal & goto :EOF
  ::
  :ProcessOneLine
  set /a lineNro_+=1
  set row=%*
  echo @set line%lineNro_%_=%row%>>"%temp%\tmp$$$.cmd"
  goto :EOF

As you'll observe, the output "is all over the place"
  @set line2_=This is line
  @set line3_=This is line
  @set line4_=This is line
  @set line5_=This is line
  @set line6_=This is line
  @set line7_=This is line
  @set line8_=This is line
  line1_=This is line 1!
  line2_=
  line3_=
  line4_=
  line5_=
  line6_=
  line7_=
  line8_=
  line9_=This is line 10
  line10_=This is line 11

This is a conundrum, but probably has to do with the trailing line
number (when a single digit) in the text file being taken as a file
handle. When I posed this situation to the regulars in alt.msdos.batch.
nt (as expected) workarounds were quickly found. Replace
  echo @set line%lineNro_%_=%row%>>"%temp%\tmp$$$.cmd"
with
  (echo @set line%lineNro_%_=%row%)>>"%temp%\tmp$$$.cmd"
or with
  >>"%temp%\tmp$$$.cmd" echo @set line%lineNro_%_=%row%

Also see item #82.

Let's return to the original task with a twist. Assuming that the file "My test file.txt" contains a single line of the form
20080621
How to generate a one line command in the CLI (i.e. not a batch file!) to echo (just) the year?
for /f %a in ('type "My test file.txt"') do @set IDate=%a&@call echo %IDate:~0,4%

References/Comments:
 http://www.google.com/groups?selm=4860ac38$0$31980$a82e2bb9%40reader.athenanews.com
 http://www.google.com/groups?selm=khty7hv05cqk$.wmvkw9l3fksi$.dlg%4040tude.net
 http://www.google.com/groups?selm=50687c38-a4d3-416e-b096-bc3ec6476145%40f36g2000hsa.googlegroups.com
 http://www.google.com/groups?selm=e2332000-54e0-4df5-bb33-b9a124e0b7b8%40w7g2000hsa.googlegroups.com
 http://groups.google.fi/group/alt.msdos.batch.nt/msg/01b35f315bc34288
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:27 2011
Subject: 87) How can I create a four-digit random string?
Date: Mon, 31 Jan 2011 01:01:27
From: ts@uwasa.fi (Timo Salmi)

For an instructive example of a CMD-commands-only script creating
random strings see "MAKEPASS.CMD Make a randomized password" included
in this package.

There is a inbuilt random generator as given by the XP Command-line
reference - Concepts - Command shell overview: The variable %RANDOM% a
random in a script will be a decimal number between 0 and 32767.
  @echo off & setlocal enableextensions
  set /a rand_=%random% %% 10000
  set rand_=0000%rand_%
  echo %rand_:~-4%
  endlocal & goto :EOF
The %% is the remainder (modulo) operator
The output might be e.g.
  C:\_D\TEST>cmdfaq
  rand_=4823

A catch is present, however. If the output is e.g.
  rand_=0968
a prefix of 0 indicates an octal number if used in calculations.
Thus as the above would be an invalid octal number because octal
numbers cannot have the digits 8 or 9. To demonstrate
  @echo off & setlocal enableextensions
  set /a x=0968
  endlocal & goto :EOF
The output would be
  C:\_D\TEST>cmdfaq
  Invalid number.  Numeric constants are either decimal (17),
  hexadecimal (0x11), or octal (021).
Thus, if it is about numbers to be used in calculations, obviously do
not pad leading zeros into the variable.

A Visual Basic Script (VBScript) aided command line script solution:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it with Microsoft Windows Script Host
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs">"%temp%\tmp$$$.cmd"
  ::
  :: Call the command line script which the script host built
  call "%temp%\tmp$$$.cmd"
  ::
  :: Display the result
  echo rand_=%rand_%
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do (
    if exist %%f del %%f)
  endlocal & goto :EOF
  '
  Randomize                                         'VBS
  MyRandom = Right("0000" & Int(10000*Rnd) , 4)     'VBS
  WScript.StdOut.WriteLine "@set rand_=" & MyRandom 'VBS
The output might be e.g.
  C:\_M>c:\_d\test\cmdfaq
  rand_=7674

One of the options is to use G(nu)AWK. The string is between 0000
and 9999. Leading zeros are added by the solution as needed.
  @echo off & setlocal enableextensions
  ::
  :: Create a random number between 0-9999
  gawk 'BEGIN{srand();printf "@set rand_=%%04d\n",int(10000*rand())}'>"%temp%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%temp%\tmp$$$.cmd"
  ::
  :: Display the result
  echo rand_=%rand_%
  endlocal & goto :EOF
The output might be e.g.
  C:\_D\TEST>cmdfaq
  rand_=0857

Incidentally, if one only needs two digits one quick-and-dirty
alternative is to take the current milliseconds: %time:~9,2%

Consider a slightly different task. Get random numbers from 1 to 52
without any repeats. Like shuffling a deck of cards numbered 1-52.
Using VBS-aided scripting and the shuffle algorithm to avoid any
repeats we get:
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Set the number of random numbers to be shuffled
  :: Typically 52 would be a deck of cards
  set max_=52
  ::
  :: Build a Visual Basic Script
  set vbs_=%mytemp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  set cmd_=%mytemp%\tmp$$$.cmd
  cscript //nologo %vbs_% > %cmd_%
  ::
  :: Call the command line script which the script host built
  call %cmd_%
  ::
  :: Display the results
  for /l %%i in (1,1,%max_%) do echo rand[%%i] = !rand[%%i]!
  ::
  :: Clean up
  for %%f in ("%vbs_%" "%cmd_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.......................................................
  'The Visual Basic Script
  '
  Dim maxItems, i, j, k, rand(1000)                     'VBS
  Set WshShell = WScript.CreateObject("WScript.shell")  'VBS
  maxItems=WshShell.ExpandEnvironmentStrings("%max_%")  'VBS
  Randomize                                             'VBS
  For i = 1 to MaxItems                                 'VBS
    rand(i) = i                                         'VBS
  Next                                                  'VBS
  For i = 1 to MaxItems                                 'VBS
    j = 1 + Int(MaxItems*rnd)                           'VBS
    k = rand(i)                                         'VBS
    rand(i) = rand(j)                                   'VBS
    rand(j) = k                                         'VBS
  Next                                                  'VBS
  For i = 1 to MaxItems                                 'VBS
    WScript.Echo "@set rand[" & i & "]=" & rand(i)      'VBS
  Next                                                  'VBS

The output would be e.g.
  C:\_D\TEST>cmdfaq
  rand[1] = 3
  rand[2] = 6
  :
  rand[50] = 36
  rand[51] = 26
  rand[52] = 40

References/Comments:
 http://www.google.com/groups?selm=423ca927%240%24548%24ed2619ec%40ptn-nntp-reader03.plus.net
 http://www.google.com/groups?selm=vT8HY5CmxKPCFwPt%40merlyn.demon.co.uk
 http://www.google.com/groups?selm=426A6578.49DD09AA%40unibwm.de
 http://www.google.com/groups?selm=v8ml611d7hjkdj59rmq9j96rttk08ed7gd%404ax.com
 http://www.google.com/groups?selm=TV1oJTHTXd7DFwcy%40merlyn.demon.co.uk
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:28 2011
Subject: 88) How to convert DEC to HEX with a script file, and vice versa?
Date: Mon, 31 Jan 2011 01:01:28
From: ts@uwasa.fi (Timo Salmi)

If you want a pure script only solution, see items 32 and 33 in this
FAQ. If you want to convert a string given in hexadecimals see item
73. For a command-line calculator type of a solution for Dec to Hex
(etc) see item 61.

This can be also done e.g. with G(nu)AWK or a Visual Basic
Script (VBScript). The gawk solutions are given below. No error
checking for the correct input format of the digits is included in
the conversion algorithms. To put the results in an environment
variable see the DEC to BIN awk and VBScript examples in this item.

  @echo off & setlocal enableextensions disabledelayedexpansion
  rem DEC to HEX
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Hexadecimal
    goto :EOF)
  ::
  :: Build an awk source
  set awksrc="%temp%\tmp$$$.awk"
  >  %awksrc% echo BEGIN{
  >> %awksrc% echo number=%1
  >> %awksrc% echo base=16
  >> %awksrc% echo digit="0123456789ABCDEF"
  >> %awksrc% echo result=""
  >> %awksrc% echo while(number!=0)
  >> %awksrc% echo  {
  >> %awksrc% echo   i=number-base*int(number/base)
  >> %awksrc% echo   result=substr(digit,i+1,1)result
  >> %awksrc% echo   number=int(number/base)
  >> %awksrc% echo  }
  >> %awksrc% echo printf"%%s\n",result
  >> %awksrc% echo }
  ::
  :: Run the awk source
  gawk -f %awksrc%
  ::
  :: Clean up
  for %%f in (%awksrc%) do if exist %%f del %%f
  endlocal & goto :EOF
An example of the output
  C:\_D\TEST>cmdfaq 127
  7F
As is seen the above can be easily generalized by changing the
"base" variable. The same goes for the other cases.

In the special case of DEC to HEX gawk inbuilt features can
alternatively be used as a simple shortcut:
    @echo off & setlocal enableextensions
    rem DEC to HEX
    ::
    if "%~1"=="" (
      echo.
      echo Usage: %~f0 [DecimalNumber] to be converted to Hexadecimal
      goto :EOF)
    ::
    gawk 'BEGIN{printf"%%X\n","%~1"}'
    ::
    endlocal & goto :EOF

The other way round the HEX to DEC code is
  @echo off & setlocal enableextensions disabledelayedexpansion
  rem HEX to DEC
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [HexNumber] to be converted to Decimal
    goto :EOF)
  ::
  :: Build an awk source
  set awksrc="%temp%\tmp$$$.awk"
  >  %awksrc% echo BEGIN{
  >> %awksrc% echo k=1
  >> %awksrc% echo d=0
  >> %awksrc% echo base=16
  >> %awksrc% echo number=toupper("%1")
  >> %awksrc% echo i=length(number)+1
  >> %awksrc% echo while(i!=1)
  >> %awksrc% echo  {
  >> %awksrc% echo   i--
  >> %awksrc% echo   j=index("123456789ABCDEF",substr(number,i,1))
  >> %awksrc% echo   d=d+j*k
  >> %awksrc% echo   k=base*k
  >> %awksrc% echo  }
  >> %awksrc% echo printf"%%s in HEX is %%s in DEC\n",number,d
  >> %awksrc% echo }
  ::
  :: Run the awk source
  gawk -f %awksrc%
  ::
  :: Clean up
  for %%f in (%awksrc%) do if exist %%f del %%f
  endlocal & goto :EOF
An example of the output
  C:\_D\TEST>cmdfaq FD
  FD in HEX is 253 in DEC

Let's consider the conversion from decimal to binary and putting the
result into an environment variable.
  @echo off & setlocal enableextensions
  rem DEC to BIN
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Binary
    goto :EOF)
  ::
  :: Build an awk source
  set awksrc="%temp%\tmp$$$.awk"
  >  %awksrc% echo BEGIN{
  >> %awksrc% echo number=%1
  >> %awksrc% echo base=2
  >> %awksrc% echo digit="0123456789ABCDEF"
  >> %awksrc% echo result=""
  >> %awksrc% echo while(number!=0)
  >> %awksrc% echo  {
  >> %awksrc% echo   i=number-base*int(number/base)
  >> %awksrc% echo   result=substr(digit,i+1,1)result
  >> %awksrc% echo   number=int(number/base)
  >> %awksrc% echo  }
  >> %awksrc% echo printf"@set bin_=%%s\n",result
  >> %awksrc% echo }
  ::
  :: Run the awk source and the created command script
  set myscript="%temp%\tmp$$$.cmd"
  gawk -f %awksrc%>%myscript%
  call %myscript%
  ::
  :: Clean up
  for %%f in (%awksrc% %myscript%) do if exist %%f del %%f
  ::
  :: Display the results
  echo %1 DEC = %bin_% BIN
  endlocal & goto :EOF
An example of the output
  C:\_D\TEST>cmdfaq 12
  12 DEC = 1100 BIN

A VBScript-aided solution for the Decimal to Binary conversion is
given below
  @echo off & setlocal enableextensions
  rem DEC to BIN
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [DecimalNumber] to be converted to Binary
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it with Microsoft Windows Script Host
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs" %1 > "%temp%\tmp$$$.cmd"
  ::
  :: Utilize the output and display the result
  call "%temp%\tmp$$$.cmd"
  echo Decimal %1 in Binary = %bin_%
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  number=WScript.Arguments.Unnamed(0)    'VBS
  base=2                                 'VBS
  digit="0123456789ABCDEF"               'VBS
  result=""                              'VBS
  While number <> 0                      'VBS
    i = number - base * Int(number/base) 'VBS
    result = Mid(digit,i+1,1) & result   'VBS
    number = Int(number/base)            'VBS
  Wend                                   'VBS
  WScript.Echo "@set bin_=" & result     'VBS
An example of the output
  C:\_D\TEST>cmdfaq 12
  Decimal 12 in Binary = 1100

Since VBScript has a Hex function, for the Decimal to Hexadecimal
the while loop and the three lines above it can simply be replaced
with
  result = Hex(number)                   'VBS
The same goes for octal.

To conclude the item one more VBScript-aided solution version:
  @echo off & setlocal enableextensions
  rem HEX to DEC
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [HexNumber] to be converted to Decimal
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it with Microsoft Windows Script Host
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs" %1 > "%temp%\tmp$$$.cmd"
  ::
  :: Utilize the output and display the result
  call "%temp%\tmp$$$.cmd"
  echo Hexadecimal %1 in Decimal = %dec_%
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  number=WScript.Arguments.Unnamed(0)                    'VBS
  k = 1                                                  'VBS
  d = 0                                                  'VBS
  base = 16                                              'VBS
  number=UCase(number)                                   'VBS
  i = Len(number) + 1                                    'VBS
  While i > 1                                            'VBS
    i = i - 1                                            'VBS
    j = Instr (1, "123456789ABCDEF", Mid(number,i,1), 0) 'VBS
    d = d + (j * k)                                      'VBS
    k = base * k                                         'VBS
  Wend                                                   'VBS
  WScript.Echo "@set dec_=" & d                          'VBS
An example of the output
  C:\_D\TEST>cmdfaq 1a
  Hexadecimal 1a in Decimal = 26

Written slightly differently
  @echo off & setlocal enableextensions
  rem HEX to DEC
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~f0 [HexNumber] to be converted to Decimal
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  :: and run it with Microsoft Windows Script Host
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%temp%\tmp$$$.vbs" %1') do set dec_=%%a
  ::
  :: Utilize the output and display the result
  echo Hexadecimal %1 in Decimal = %dec_%
  ::
  :: Clean up
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  number=WScript.Arguments.Unnamed(0) 'VBS
  k = 1 'VBS
  d = 0 'VBS
  base = 16 'VBS
  number=UCase(number) 'VBS
  i = Len(number) + 1 'VBS
  While i > 1 'VBS
    i = i - 1 'VBS
    j = Instr (1, "123456789ABCDEF", Mid(number,i,1), 0) 'VBS
    d = d + (j * k) 'VBS
    k = base * k 'VBS
  Wend 'VBS
  WScript.Echo d 'VBS
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:29 2011
Subject: 89) All of a sudden "echo." doesn't work any more. What's wrong?
Date: Mon, 31 Jan 2011 01:01:29
From: ts@uwasa.fi (Timo Salmi)

Echo is an internal command. One probable cause is that for some
reason you have accidentally created a file with that same name into
the current directory. Consider this demonstration
  @echo off & setlocal enableextensions
  echo whatever>echo
  echo An error will occur:
  echo.
  del echo
  echo No more the error
  echo.
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  An error will occur:
  'echo.' is not recognized as an internal or external command,
  operable program or batch file.
  No more the error

For another catch see item 82) Why does echo 9>temp.txt fail while
echo 10>temp.txt works?

Another case of seemingly unexpected (but logical) results could arise from
  @echo off & setlocal enableextensions
  set var=<space>
  if "%var%"=="" (echo var is empty) else (echo var is not empty)
  endlocal & goto :EOF

The output will be
  C:\_D\TEMP>cmdfaq
  var is not empty

References/Comments:
 http://www.google.com/groups?selm=7ecf093b-0932-421d-b84a-4b2de35587a4%40z24g2000prf.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:30 2011
Subject: 90) How do I get the most recent file within a directory structure?
Date: Mon, 31 Jan 2011 01:01:30
From: ts@uwasa.fi (Timo Salmi)

Pinpointing the most recent file in a folder is not very difficult
  @echo off & setlocal enableextensions
  set myfolder_=C:\WhateverTheFolder
  for /f "delims=" %%f in (
    'dir /o:d /a:-d /b "%myfolder_%\*.*"') do (
    set latest_=%myfolder_%\%%~nxf)
  if defined latest_ (
    echo rem DoWhatever "%latest_%"
    ) else (
    echo No designated files found in "%myfolder_%")
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  rem DoWhatever "C:\WhateverTheFolder\MyRecent.txt"
Depending on your task, you might have something else than *.* like
*.LOG

Getting the most recent file in an entire directory structure is
a bit more complicated:
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Define the root folder of the search
  set rootFolder=C:\WhateverTheFolder
  ::
  :: Ensure that the auxiliary directory file does not already exist
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  if exist %temp_%temp.dir del %temp_%temp.dir
  ::
  :: Make a directory with the date/time as YYYYMMDD HH:MM
  :: Assumes a DD.MM.YYYY date and a 24-hour time, i.e. no am/pm
  for /f "tokens=*" %%f in (
      'dir "%rootFolder%\*.*" /s /b /-c /a:-d-s-h /o:d') do (
    set fdate_=%%~tf
    set fRevisedDate_=!fdate_:~6,4!!fdate_:~3,2!!fdate_:~0,2!
    set ftime_=!fdate_:~11,2!!fdate_:~14,2!
    echo !fRevisedDate_! !ftime_! "%%f">>%temp_%temp.dir)
  ::
  :: Was anything found
  if not exist %temp_%temp.dir (
    echo No designated files found in "%rootFolder%" or below
    goto :EOF)
  ::
  :: Sort the directory listing by the date/time stamp
  sort %temp_%temp.dir /o %temp_%tempsort.dir
  ::
  :: Get the last line of the sorted directory listing
  for /f "delims=" %%r in ('type %temp_%tempsort.dir') do (
    set LastLine_=%%r)
  echo.%LastLine_%
  ::
  :: Clean up
  for %%f in (temp.dir tempsort.dir) do (
    if exist %temp_%%%f del %temp_%%%f)
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  20050414 1742 "C:\_F\VPP\DAT\TSKP6504.WKT"

If you want only the filename, substitute
  echo.%LastLine_:~14%

There is a catch, however. Since enabledelayedexpansion has been
applied, the file names with exclamation marks would miss the
exclamation mark! To circumvent this dilemma, use a subroutine call
instead.
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Define the root folder of the search
  set rootFolder=C:\WhateverTheFolder
  ::
  :: Ensure that the auxiliary directory file does not already exist
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  if exist %temp_%temp.dir del %temp_%temp.dir
  ::
  :: Make a directory with the date/time as YYYYMMDD HH:MM
  :: Assumes a DD.MM.YYYY date and a 24 hour time, i.e. no am/pm
  for /f "tokens=*" %%f in (
    'dir "%rootFolder%\*.*" /s /b /-c /a:-d-s-h /o:d') do (
    call :PutInfo "%%~ff")
  ::
  :: Was anything found
  if not exist %temp_%temp.dir (
    echo No designated files found in "%rootFolder%" or below
    goto :EOF)
  ::
  :: Sort the directory listing by the date/time stamp
  sort %temp_%temp.dir /o %temp_%tempsort.dir
  ::
  :: Get the last line of the sorted directory listing
  for /f "delims=" %%r in ('type %temp_%tempsort.dir') do (
    set LastLine_=%%r)
  echo.%LastLine_%
  ::
  :: Clean up
  for %%f in (temp.dir tempsort.dir) do (
    if exist %temp_%%%f del %temp_%%%f)
  endlocal & goto :EOF
  ::
  :: =======================================================
  :PutInfo
  setlocal enableextensions disabledelayedexpansion
    set fdate_=%~t1
    set fRevisedDate_=%fdate_:~6,4%%fdate_:~3,2%%fdate_:~0,2%
    set ftime_=%fdate_:~11,2%%fdate_:~14,2%
    >>%temp_%temp.dir echo %fRevisedDate_% %ftime_% "%~1"
  endlocal & goto :EOF

How about getting the last five most recent files instead of the
latest only? One option is
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Define the root folder of the search
  set rootFolder=C:\WhateverTheFolder
  ::
  :: Ensure that the auxiliary directory file does not already exist
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  if exist %temp_%temp.dir del %temp_%temp.dir
  ::
  :: Make a directory with the date/time as YYYYMMDD HH:MM
  :: Assumes a DD.MM.YYYY date and a 24-hour time, i.e. no am/pm
  for /f "tokens=*" %%f in (
    'dir "%rootFolder%\*.*" /s /b /-c /a:-d-s-h /o:d') do (
    call :PutInfo "%%~ff")
  ::
  :: Was anything found
  if not exist %temp_%temp.dir (
    echo No designated files found in "%rootFolder%" or below
    goto :EOF)
  ::
  :: Sort the directory listing by the date/time stamp
  sort /r %temp_%temp.dir /o %temp_%tempsort.dir
  ::
  :: Get the first five lines of the sorted directory listing
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
  cscript //nologo "%temp%\tmp$$$.vbs" < %temp_%tempsort.dir
  ::
  :: Clean up
  for %%f in (temp.dir tempsort.dir) do (
    if exist %temp_%%%f del %temp_%%%f)
  if exist "%temp%\tmp$$$.vbs" del "%temp%\tmp$$$.vbs"
  endlocal & goto :EOF
  ::
  :: =======================================================
  :PutInfo
  setlocal enableextensions disabledelayedexpansion
    set fdate_=%~t1
    set fRevisedDate_=%fdate_:~6,4%%fdate_:~3,2%%fdate_:~0,2%
    set ftime_=%fdate_:~11,2%%fdate_:~14,2%
    >>%temp_%temp.dir echo %fRevisedDate_% %ftime_% "%~1"
  endlocal & goto :EOF
  '
  '...............................................................
  'A Visual Basic "head -5" Script to display the first five lines
  i = 0 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    i = i + 1 'VBS
    If i > 5 Then Exit Do 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    WScript.StdOut.WriteLine str 'VBS
  Loop 'VBS

The output could be e.g.
  C:\_D\TEST>cmdfaq
  20050414 2237 "C:\_D\BAS\TEST 2.CMD"
  20050415 1205 "C:\_D\OPETUS\JATKO\JATKOP.XLS"
  20050415 2002 "C:\_D\WORD\TIMOSUOM.DIC"
  20050415 2120 "C:\_D\OPETUS\JOTT\TUL\JOTTTUL.MAI"
  20050415 2351 "C:\_D\TEST\CMDFAQ.CMD"

Another approach to the task at hand would be to customize
 RECENT.CMD CMD shell for RECENT.VBS
 RECENT.VBS Search folders for recent files
They are included as separate files in this CMD FAQ package. The
advantage of the VBS solution is that the date/time stamps will
cover also seconds.

References/Comments:
 http://www.google.com/groups?selm=xFXgtLApDsXCFwsF%40merlyn.demon.co.uk
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:31 2011
Subject: 91) How do I get command-line reference help?
Date: Mon, 31 Jan 2011 01:01:31
From: ts@uwasa.fi (Timo Salmi)

Besides the obvious
 HELP
or for individual commands e.g.
 HELP /?
one can invoke the desktop version of the Command-line reference
 hh %SYSTEMROOT%\Help\ntcmds.chm

For a single command one can use e.g. the following alternatives
 FOR /?
 HELP FINDSTR | MORE
 hh ntcmds.chm::/set.htm

For putting all the help into continuous text file use
  @echo off & setlocal enableextensions
  if exist help.txt del /p help.txt
  for /f %%f in ('help') do (
    >>help.txt help %%f
    >>help.txt echo ----------------------------------------------------------
    >>help.txt echo.
    )
  endlocal & goto :EOF

If you need install Microsoft Windows Script 5.6 for Windows 2000
and XP including Visual Basic Script Edition (VBScript.) you can
look "Script56.CHM" up at Google or start from
 http://www.microsoft.com/downloads/
and then take up the search for "Microsoft Windows Script 5.6". When
you have it installed, the compiled HTML Help file can be called
e.g. with something like
hh "C:\Program Files\Microsoft Windows Script\ScriptDocs\Script56.CHM"

A tip from Walter Briscoe:
"hh -decompile . %SYSTEMROOT%\Help\ntcmds.chm" writes a huge amount
of .htm files in the current directory.

References/Comments:
  http://www.netikka.net/tsneti/info/tscmd.php#references
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:32 2011
Subject: 92) How do I play a sound from the command line?
Date: Mon, 31 Jan 2011 01:01:32
From: ts@uwasa.fi (Timo Salmi)

The simplest way to emit a brief beep is
 @echo <Ctrl-G>

How to enter the ASCII 7 character depends on your editor program. One
fairly common way of entering the beep character is entering 007 from
the numeric keypad while holding down the ALT key. Or you could even
put the character as follows in a file and copypaste it from there.
  gawk 'BEGIN{printf "%%s","\x07"}'>beepchar.txt
or
  gawk 'BEGIN{printf "@rem %%s\n","\x07"}'>>myfile.cmd

If you can get hold of QBASIC it has a PLAY statement. For example
  @echo off & setlocal enableextensions
  set bas_=%temp%\tmp$$$.bas
  for /f "tokens=*" %%f in ("%bas_%") do set bas_=%%~sf
  > %bas_% echo PLAY "l8 o3 cdefgab o4 cd"
  >>%bas_% echo SYSTEM
  qbasic /run %bas_%
  for %%f in (%bas_%) do if exist %%f del %%f
  endlocal & goto :EOF

The Sound Recorder can be used to play a Wave Audio Sound file
(.WAV). For example
 sndrec32.exe /play /close %SYSTEMROOT%\Media\tada.wav
or, without displaying the Sound Recorder window on the desktop
 start /min "" sndrec32 /play /close %SYSTEMROOT%\Media\tada.wav

References/Comments:
 http://support.microsoft.com/kb/q168789/
 http://www.google.com/groups?selm=uJqTHMN9EHA.1400%40TK2MSFTNGP11.phx.gbl
 http://www.google.com/groups?selm=426a617e.3383905%40news.comporium.net
 http://www.google.com/groups?selm=6ZEKnHHix%2bTIFwE9%40invalid.uk.co.demon.merlyn.invalid
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:33 2011
Subject: 93) How do I check if my script was given a parameter?
Date: Mon, 31 Jan 2011 01:01:33
From: ts@uwasa.fi (Timo Salmi)

Back to the very basics, with some additions. The most common test for
detecting if any batch parameters are given is
  @echo off & setlocal enableextensions
  if not "%~1"=="" echo.%~1
  endlocal & goto :EOF

For example one might have
  C:\_D\TEST>cmdfaq "a b"
  a b
or
  C:\_D\TEST>cmdfaq "^&^(^)[]{}^^=;!'+,`~^<^>"
  &()[]{}^=;!'+,`~<>

If we omit the ~ modifier which removes any surrounding quotation
marks ("") we might have e.g.
  @echo off & setlocal enableextensions
  if not "%1"=="" echo.%1
  endlocal & goto :EOF

C:\_D\TEST>cmdfaq "a b"
  b""=="" was unexpected at this time.
  or
  C:\_D\TEST>cmdfaq "a" "b"
  "a"

However,
  @echo off & setlocal enableextensions
  set par1=%1
  if defined par1 echo %1
  endlocal & goto :EOF

  C:\_D\TEST>cmdfaq "a b"
  "a b"

It is obvious that one has to be mindful of the quotes and the usage
of the ~ modifier.

For more on parsing the parameters, see e.g. item #40.

References/Comments:
 hh ntcmds.chm::/percent.htm
 http://www.google.com/groups?selm=43275252%240%2497135%24ed2619ec%40ptn-nntp-reader03.plus.net
 http://www.google.com/groups?selm=443e85ec%240%247489%249b536df3%40news.fv.fi
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:34 2011
Subject: 94) Can I send the script's output both to the screen and a log file?
Date: Mon, 31 Jan 2011 01:01:34
From: ts@uwasa.fi (Timo Salmi)

One option is to use the UNIX-like tee.exe f you can find one on the
net.

To show an example apply that on the CMDFAQ.CMD script containing
  @echo off & setlocal enableextensions
  if not [%1]==[] echo %1
  if not [%1]==[] echo %~1
  if not "%1"=="" echo %1
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq "a b" | tee MyLog.txt
  "a b"
  a b
  b""=="" was unexpected at this time.

  C:\_D\TEST>type MyLog.txt
  "a b"
  a b
The error message goes to stdout only.

Another option is to use any suitable screen capture program.

A third one is to write a VBS cscript to do the "tee". Consider the
following example script
  @echo off & setlocal enableextensions
  rem MYTEST.CMD
  echo Test row 1
  echo Test row 2
  endlocal & goto :EOF

Make and store the following TEE.VBS file at your path
  Dim str
  Do While Not WScript.StdIn.AtEndOfStream
    str = WScript.StdIn.ReadLine
    WScript.StdOut.WriteLine str
    WScript.StdErr.WriteLine str
  Loop

Then on the command line call
  MYTEST | cscript /nologo TEE.VBS > MYLOG.TXT
The output on the screen will be
  C:\_M>MYTEST | cscript /nologo TEE.VBS > MYLOG.TXT
  Test row 1
  Test row 2
And you can ascertain
  C:\_M>type mylog.txt
  Test row 1
  Test row 2

Also gawk could be used. For example call the following script
  @echo off & setlocal enableextensions
  echo Test row 1
  echo Test row 2
  endlocal & goto :EOF
from the command line using
  CMDFAQ|gawk "{print; print>\"c:\\_m\\out.txt\"}"
The output will be
  C:\_D\TEST>C:\_D\BAS\CMDFAQ.CMD|gawk "{print; print>\"c:\\_m\\out.txt\"}"
  Test row 1
  Test row 2
and the file c:\_m\out.txt will also contain
  Test row 1
  Test row 2

One could, of course, write "bare-batch" subroutines for selective
"teeing". For example
  @echo off & setlocal enableextensions
  rem MYTEST.CMD
  set MyLogfile=C:\_M\mylog.txt
  if exist "%MyLogfile%" del "%MyLogfile%"
  call :teeEcho "Test row ^1"
  call :teeEcho "Test row ^2"
  call :teeDir "C:\_D\TEST\*.*"
  endlocal & goto :EOF
  ::
  :teeEcho
  setlocal
  set row_=%~1
  echo %row_%
  echo %row_%>>"%MyLogfile%"
  goto :EOF
  ::
  :teeDir
  setlocal
  set row_=%~1
  dir %row_%
  dir %row_%>>"%MyLogfile%"
  goto :EOF

The situation is, however, far from as simple as you might think. In
the call :teeEcho the quoting is needed to pass on the entire
argument. (Also note employing %~1 rather than %*). Most importantly,
and subtly, the 1 and 2 need be escaped with the caret ^ lest they
are (mis)taken for file handles! Else the output will not be what you
except. There is, however, a better way round the problem:
  @echo off & setlocal enableextensions
  rem MYTEST.CMD
  set MyLogfile=C:\_M\mylog.txt
  if exist "%MyLogfile%" del "%MyLogfile%"
  call :teeEcho Test row 1
  call :teeEcho Test row 2
  call :teeDir "C:\_D\TEST\*.*"
  endlocal & goto :EOF
  ::
  :teeEcho
  setlocal
  echo %*
  >>"%MyLogfile%" echo %*
  endlocal & goto :EOF
  ::
  :teeDir
  setlocal
  dir %*
  >>"%MyLogfile%" dir %*
  endlocal & goto :EOF
Unfortunately, even that (better) solution breaks down with some
poison characters in the passed text like & the ampersand. The batch-
subroutine method of teeing simply is subject to pitfalls.

Consider a similar question. How does one always direct the header
output of a script to the console (screen), but the body optionally
either to the screen or a file? As an example search through a set of
CMD and BAT files to identify which ones include the string "%ram%",
the quotes inclusive.
  @echo off & setlocal enableextensions
  (
    echo +----------------------------------------------------+
    echo ^| Search a list of BAT and CMD files for a string    ^|
    echo ^| By Prof. Timo Salmi, Last modified Sat 18-Apr-2009 ^|
    echo +----------------------------------------------------+
  )>con
  set SearchString=\"%%ram%%\"
  findstr /s /m /c:"%SearchString%" "C:\_E\*.BAT"
  findstr /s /m /c:"%SearchString%" "C:\_E\*.CMD"
  findstr /s /m /c:"%SearchString%" "C:\_F\*.BAT"
  findstr /s /m /c:"%SearchString%" "C:\_F\*.CMD"
  endlocal & goto :EOF

Normally, the screen output would be something like
  C:\_M>C:\_D\TEST\CMDFAQ.CMD
  +----------------------------------------------------+
  | Search a list of BAT and CMD files for a string    |
  | By Prof. Timo Salmi, Last modified Sat 18-Apr-2009 |
  +----------------------------------------------------+
  C:\_E\ARCZIP\HOME.BAT
  C:\_E\ARCZIP\PHREN.BAT
  :
  C:\_F\XTOOLS\CLRM.CMD
  C:\_F\XTOOLS\CMDBOX.CMD

However
  C:\_M>C:\_D\TEST\CMDFAQ.CMD > "MyLog.txt"
  +----------------------------------------------------+
  | Search a list of BAT and CMD files for a string    |
  | By Prof. Timo Salmi, Last modified Sat 18-Apr-2009 |
  +----------------------------------------------------+
with all the rest of the output sent to MyLog.txt

References/Comments:
 http://www.google.com/groups?selm=42748127%240%24558%24ed2e19e4%40ptn-nntp-reader04.plus.net
 http://www.google.com/groups?selm=1152391556.019753.306150%40m79g2000cwm.googlegroups.com
 http://www.google.com/groups?selm=12avdq4emlftb85%40corp.supernews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:35 2011
Subject: 95) How to perform an operation on all the filenames listed in a file?
Date: Mon, 31 Jan 2011 01:01:35
From: ts@uwasa.fi (Timo Salmi)

Slightly different variants of this Frequently Asked Question have
been answered many times over. But let's look at this rendition.
Assume that you have in MyList.txt e.g. the following information. The
information could be there for example as a result of a search with
the DIR command.
  C:\Documents and Settings\ts\Local Settings\Temp\GLB62.tmp
  C:\Documents and Settings\ts\Local Settings\Temp\~DF3A.tmp
  C:\WINDOWS\SET3.tmp
  C:\WINDOWS\system32\CONFIG.TMP
  C:\WINDOWS\Temp\scs17.tmp
  C:\_L\TIMO\EXTENS01\EXTEN01.TMP

The script to build MyTask.cmd which you can then call separately.
  @echo off & setlocal enableextensions
  ::
  :: The command you want to perform on each row.
  :: The "rem" has been inserted for safety
  set todo_=rem del /p
  ::
  :: Delete any old remnants
  for %%f in ("MyTask.cmd") do if exist %%f del %%f
  ::
  :: Add the todo_ command at the beginning of each line
  :: Put use quotes in case the source file contains long file names
  for /f "delims=" %%r in ('type MyList.txt') do (
    >> "MyTask.cmd" echo %todo_% "%%~r")
  ::
  :: Display the outcome also on the screen
  type "MyTask.cmd"
  echo.
  dir "MyTask.cmd"|find /i "MyTask.cmd"
  echo Is ready to be run
  ::
  :: Clean up
  for %%f in ("MyTask.cmd") do if exist %%f del %%f
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  rem del /p "C:\Documents and Settings\ts\Local Settings\Temp\GLB62.tmp"
  rem del /p "C:\Documents and Settings\ts\Local Settings\Temp\~DF3A.tmp"
  rem del /p "C:\WINDOWS\SET3.tmp"
  rem del /p "C:\WINDOWS\system32\CONFIG.TMP"
  rem del /p "C:\WINDOWS\Temp\scs17.tmp"
  rem del /p "C:\_L\TIMO\EXTENS01\EXTEN01.TMP"

  03.05.2005  12:35               317 MyTask.cmd
  Is ready to be run

What about making the MyList.txt list. The origin could be anything,
but below is a familiar example how to list all today's *.TMP files
into it.
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Get today's date elements, locale dependent
  set dd_=%date:~0,2%
  set mm_=%date:~3,2%
  set yyyy_=%date:~6,4%
  ::
  :: List all *.TMP file made today
  for /f "delims=" %%f in (
    'dir "C:\*.tmp" /s /b /-c /a:-d-s-h') do (
      set fdate_=%%~tf
      set fdd_=!fdate_:~0,2!
      set fmm_=!fdate_:~3,2!
      set fyyyy_=!fdate_:~6,4!
      if !fyyyy_!!fmm_!!fdd_! EQU %yyyy_%%mm_%%dd_% (
        >> "MyList.txt" echo %%~f)
    )
  endlocal & goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:36 2011
Subject: 96) Can one use a script to columnize a comma separated values file?
Date: Mon, 31 Jan 2011 01:01:36
From: ts@uwasa.fi (Timo Salmi)

Yes, as shown below
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Make a test Comma Separated Value file
  set myfile_=MyFile.csv
  > "%myfile_%" echo a,b,c,de
  >>"%myfile_%" echo a2,b2,c2,de2
  >>"%myfile_%" echo 3,b b3,c234567890,de3
  ::
  :: Columnize
  for /f "tokens=1-4 delims=," %%a in ('type "%myfile_%"') do (
   set p1=%%a         .
   set p2=%%b         .
   set p3=%%c         .
   set p4=%%d         .
   echo !p1:~0,9! !p2:~0,9! !p3:~0,9! !p4:~0,9!
   )
  ::
  :: Delete the test file
  for %%f in ("%myfile_%") do if exist %%f del %%f
  endlocal & goto :EOF

The Comma Separated Value file contains
  a,b,c,de
  a2,b2,c2,de2
  3,b b3,c234567890,de3

The test output will be
  C:\_D\TEST>cmdfaq
  a         b         c         de
  a2        b2        c2        de2
  3         b b3      c23456789 de3

The method makes it easy to rearrange the columns, if need be. One
only has to change the order of the fields on the echo line. This
may come handy, in both the directions, in e.g. presenting address
books in different formats. The column format is much easier for a
human to read than csv-formatted address information.

To accomodate potential exclamation marks the code could be rewritten
as (c.f. item #146)
  @echo off & setlocal enableextensions disabledelayedexpansion
  ::
  :: Make a test Comma Separated Value file
  set myfile_=MyFile.csv
  > "%myfile_%" echo a,b,c,de
  >>"%myfile_%" echo a2,b2,c2,de2
  >>"%myfile_%" echo 3,b b3,c234567890,de3
  ::
  :: Columnize
  for /f "tokens=1-4 delims=," %%a in ('type "%myfile_%"') do (
    set p1=%%a         .
    set p2=%%b         .
    set p3=%%c         .
    set p4=%%d         .
    call echo %%p1:~0,9%% %%p2:~0,9%% %%p3:~0,9%% %%p4:~0,9%%
    )
  ::
  :: Delete the test file
  for %%f in ("%myfile_%") do if exist %%f del %%f
  endlocal & goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:37 2011
Subject: 97) I need to remove duplicate entries from the output or a file.
Date: Mon, 31 Jan 2011 01:01:37
From: ts@uwasa.fi (Timo Salmi)

Translating Eric Pement's solutions from his UNIX-flavored SED
collection, his option is
  sed "$!N; /^\(.*\)\n\1$/!P; D"

To test it, let's have
  @echo off & setlocal enableextensions
  ::
  :: Make a test file
  set myfile_=MyFile.txt
  for %%f in ("%myfile_%") do if exist %%f del %%f
  for %%i in (1 2 2 2) do >>"%myfile_%" echo This is line %%i
  >>"%myfile_%" echo.
  for %%i in (6 6 8) do >>"%myfile_%" echo This is line %%i
  ::
  <"%myfile_%" sed "$!N; /^\(.*\)\n\1$/!P; D"
  ::
  :: Clean up
  for %%f in ("%myfile_%") do if exist %%f del %%f
  endlocal & goto :EOF

The contents of MyFile.txt will be
  This is line 1
  This is line 2
  This is line 2
  This is line 2

  This is line 6
  This is line 6
  This is line 8

and the output will be
C:\_D\TEST>cmdfaq
  This is line 1
  This is line 2

  This is line 6
  This is line 8

If one uses third party utilities, and is prepared to go beyond awk/
sed then a uniq.exe UNIX port is one option.

A Visual Basic Script (VBScript) aided solution demonstration as the
third option:
  @echo off & setlocal enableextensions
  ::
  :: Make a test file
  set myfile_=MyFile.txt
  for %%f in ("%myfile_%") do if exist %%f del %%f
  for %%i in (1 2 2 2) do >>"%myfile_%" echo This is line %%i
  >>"%myfile_%" echo.
  for %%i in (6 6 8) do >>"%myfile_%" echo This is line %%i
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  <"%myfile_%" cscript //nologo "%vbs_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%" "%myfile_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.............................................
  'The Visual Basic Script
  '
  prev = "" 'VBS
  first = true 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    If (str <> prev) Or first Then 'VBS
      WScript.StdOut.WriteLine str 'VBS
    End If 'VBS
    prev = str 'VBS
    first = false 'VBS
  Loop 'VBS

The input and output will be as in the sed solution earlier.

If(!) you are prepared to accept omitting empty lines and ignore
potential exclamation marks and other special character dilemmas, then
with a pure script
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Make a test file
  set myfile_=MyFile.txt
  for %%f in ("%myfile_%") do if exist %%f del %%f
  for %%i in (1 2 2 2) do >>"%myfile_%" echo This is line %%i
  >>"%myfile_%" echo.
  for %%i in (6 6 8) do >>"%myfile_%" echo This is line %%i
  ::
  :: Process
  set prev=
  for /f "delims=" %%a in ('type "%myfile_%"') do (
    set str=%%a
    if not [!str!]==[!prev!] echo %%a
    set prev=!str!
    )
  ::
  :: Clean up
  for %%f in ("%myfile_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output will be (note the dropping of the empty line)
C:\_D\TEST>cmdfaq
  This is line 1
  This is line 2
  This is line 6
  This is line 8

Can this task be solved with a pure cmd script so that the empty lines
are not omitted? Yes, but the solution is a bit kludgy and
complicated. And the issue of the poison characters remains.
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Make a test file
  set myfile_=MyFile.txt
  for %%f in ("%myfile_%") do if exist %%f del %%f
  for %%i in (1 2 2 2) do >>"%myfile_%" echo This is line %%i
  >>"%myfile_%" echo.
  for %%i in (6 6 8) do >>"%myfile_%" echo This is line %%i
  ::
  :: Process
  for %%v in (prev LineCount) do set %%v=
  for /f "delims=" %%a in (
    'findstr /n /v /c:"SomeUnlikelyString" Myfile.txt') do (
      set str=%%a
      set /a LineCount+=1
      set /a mod = LineCount/10 + 2
      call :WriteOneLine "!str!" "!prev!" !mod!
      set prev=!str!
      )
  ::
  :: Clean up
  for %%f in ("%myfile_%") do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  :: =============================================
  :WriteOneLine
  setlocal
  set str=%~1
  set prev=%~2
  set offset=%3
  set str=!str:~%offset%!
  set prev=!prev:~%offset%!
  if not [!str!]==[!prev!] echo.!str!
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  This is line 1
  This is line 2

  This is line 6
  This is line 8

There is, however, a concise pure script solution which drops the
duplicate lines irrespective of their location in the original file.
It also drops all the empty lines. Recall that the original test file
is
  This is line 1
  This is line 2
  This is line 2
  This is line 2

  This is line 6
  This is line 6
  This is line 8

  @echo off & setlocal enableextensions
  ::
  :: Make the test file
  set oldfile_=C:\_M\MyOldFile.txt
  set newfile_=C:\_M\MyNewFile.txt
  for %%f in ("%oldfile_%") do if exist %%f del %%f
  for %%i in (1 2 2 2) do >>"%oldfile_%" echo This is line %%i
  >>"%oldfile_%" echo.
  for %%i in (6 6 8) do >>"%oldfile_%" echo This is line %%i
  ::
  :: Start from scratch
  for %%f in ("%newfile_%") do if exist %%f del %%f
  ::
  :: Pick unique lines from the original file, i.e. our test file
  for /f "tokens=* delims=" %%a in ('type "%oldfile_%"') do (
  find /i "%%a" "%newfile_%">nul
  if errorlevel 1 echo %%a>>"%newfile_%"
  )
  ::
  :: Display the result
  type "%newfile_%"
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  File not found - C:\_M\MYNEWFILE.TXT
  This is line 1
  This is line 2
  This is line 6
  This is line 8
Note using if errorlevel 1 instead of if !errorlevel! GTR 0 to avoid
the need of using an enabledelayedexpansion.

To put things in perspective. By quite a coincidence I needed the
other day to perform that task myself combining two lists of
newsgroups and then removing the duplicates. I didn't have to think
for one second which route to take when the situation came up for
real. Skipped all the nice and fancy scripts and chose the UNIX port
uniq.exe without any hesitation.

References/Comments:
 http://www.google.com/groups?selm=d59ur0%24182m%241%40agate.berkeley.edu
 http://www.google.com/groups?selm=427aef2c%241_2%40alt.athenanews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:38 2011
Subject: 98) How do I equate all zip files with the date of their latest file?
Date: Mon, 31 Jan 2011 01:01:38
From: ts@uwasa.fi (Timo Salmi)

A typical archive maintainer's task.
  @echo off & setlocal enableextensions
  rem
  rem Covert a zip file datestamp to equal the datestamp of the
  rem most recent file within the zip archive. Traverses all the
  rem zip files in the default folder.
  rem
  rem Needs zip.exe from
  rem  355508 Oct 19 2008 zip300xn.zip
  rem  zip300xn.zip Info-ZIP command-line zip for Win9x/NT/2K/XP/2K3
  rem or more generally http://garbo.uwasa.fi/win95/arcers.html
  rem
  rem Uses the switch "-o" to "make zipfile as old as latest entry"
  rem
  rem By Prof. Timo Salmi
  rem Last modified Sun 27-Dec-2009
  ::
  set ziprog=C:\_F\FTOOLS\ZIP.EXE
  :: The zip-program needs the local Time Zone information
  set tz_=%TZ%
  set TZ=Europe/Helsinki
  :: Check that there are zip files to be processed
  if not exist "*.zip" goto _nofile
  :: Do the timestamping
  for %%f in ("*.zip") do "%ziprog%" -o %%f
  :: Show the results
  dir "*.zip" | find /i ".ZIP"
  :: Restore the original Time Zone variable in case it had a different value
  set TZ=%tz_%
  goto _out
  ::
  :_nofile
  echo No .zip files found to process
  goto _out
  ::
  :_out
  endlocal & goto :EOF

Before running the script we might have
  27.12.2009  20:07            21,678 test.zip
  27.12.2009  19:46         1,178,993 XPAD_.ZIP
The output could be e.g.
  C:\_D\TEST>C:\_D\TOOLS\ZIPOTS.CMD
  16.10.2009  12:41            21,678 test.zip
  07.12.2009  07:33         1,178,993 XPAD_.ZIP

If, instead of the Info-ZIP zip program you have the command-line
module for Winzip, substitute
  set ziprog=C:\Program Files\WinZip\WZZIP.EXE
    and
  for %%f in ("*.zip") do "%ziprog%" -o %%f -x"*.*"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:39 2011
Subject: 99) How do I "touch" a file to update its last modified datestamp?
Date: Mon, 31 Jan 2011 01:01:39
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  if [%1]==[] (
    echo Usage: %~0 ["FileName"]
    echo Wildcards allowed
    goto :EOF
    )
  for %%f in ("%~1") do copy /b /v %%f +,,> nul
  dir "%~1"
  endlocal & goto :EOF

Also see item #134.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:40 2011
Subject: 100) How can I identify and copy the five latest files from a folder?
Date: Mon, 31 Jan 2011 01:01:40
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions enabledelayedexpansion
  set count_=0
  for /f "delims=" %%f in (
    'dir /o:-d /a:-d /b c:\MyFolder\*.*') do (
    set file_="%%~ff"
    set /a count_+=1
    if !count_! LEQ 5 echo rem copy !file_!
    )
  endlocal & goto :EOF

Given that solution it is as easy to identify the five oldest
files. Left as an exercise.

The problem with the solution above is that it can't handle file names
with exclamation marks! To counter that, use
  @echo off & setlocal enableextensions disabledelayedexpansion
  set count_=0
  for /f "delims=" %%f in (
    'dir /o:-d /a:-d /b c:\_d\bas\*.*') do (
    call :SubCount "%%~ff")
  endlocal & goto :EOF
  ::
  :SubCount
  set /a count_+=1
  if %count_% LEQ 5 echo rem copy %1
  goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:41 2011
Subject: 101) How to capture Volume Serial Number into an environment variable?
Date: Mon, 31 Jan 2011 01:01:41
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  for /f "skip=1 tokens=5" %%s in ('vol c:') do set volc_=%%s
  echo %volc_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  D634-E1B2

Why the skip=1? Do the "math". Since the output of
  C:\_D\TEST>vol c:
   Volume in drive C is MYCDIVE
   Volume Serial Number is D634-E1B2

Likewise, you can fairly easily get the label of a volume:
  @echo off & setlocal enableextensions
  set target_=C:\
  for /f "tokens=6" %%f  in (
    'dir %target_%^|find "Volume in drive "') do (
    set label_=%%f)
  echo The label of Volume %target_% is %label_%
  endlocal & goto :EOF

  C:\_D\TEST>cmdfaq
  The label of Volume C:\ is MYCDRIVE

The task of finding the Volume Serial Number can also be programmed as
a subroutine, including at the same time a slightly more advanced
handling
  @echo off & setlocal enableextensions
  set dr_=C
  if not "%~1"=="" set dr_=%~1
  call :GetVolSerialNr %dr_% ser_
  echo %ser_%
  endlocal & goto :EOF
  ::
  ::===============================================================
  :GetVolSerialNr
  setlocal enableextensions
  set return_=NoInfo
  dir %~1: > "%temp%\tmp$$$.dir" 2>&1
  find "The system cannot find the path specified" "%temp%\tmp$$$.dir" > nul
  if %errorlevel% EQU 0 (set return_=DeviceNotFound&goto _endGetVolSerialNr)
  dir %~1: > "%temp%\tmp$$$.dir" 2>&1
  find "The device is not ready" "%temp%\tmp$$$.dir" > nul
  if %errorlevel% EQU 0 (set return_=DeviceNotReady&goto _endGetVolSerialNr)
  for /f "skip=1 tokens=5" %%s in ('vol %~1:') do set return_=%%s
  :_endGetVolSerialNr
  for %%f in ("%temp%\tmp$$$.dir") do if exist %%f del %%f
  endlocal & set %2=%return_%&goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  D634-E1B2
or
  C:\_D\TEST>cmdfaq E
  DeviceNotFound
or
  C:\_D\TEST>cmdfaq N
  DeviceNotReady

It might be instructive to also have a Visual Basic Script solution.
First, the volume name:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  for /f "delims=" %%a in ('cscript //nologo "%vbs_%" "%CD%"') do (
    set s_=%%a)
  ::
  :: Display the result
  echo %s_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Set arg = WScript.Arguments 'VBS
  Wscript.Echo ShowVolumeInfo(arg(0)) 'VBS
  '
  Function ShowVolumeInfo(drvpath) 'VBS from the Windows Script Documentation
    Dim fso, d, s 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set d = fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName(drvpath))) 'VBS
    s = "Drive " & d.DriveLetter & ": - " & d.VolumeName 'VBS
    ShowVolumeInfo = s 'VBS
  End Function 'VBS

The output might be e.g.
  C:\_D\TEST>cmdfaq
  Drive C: - MYCDRIVE

GetAbsolutePathName: Returns a complete and unambiguous path from a
provided path specification.
GetDriveName: Returns a string containing the name of the drive for a
specified path.
GetDrive: Returns a Drive object corresponding to the drive in a
specified path.

Likewise:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  for /f "delims=" %%a in ('cscript //nologo "%vbs_%" "%CD%"') do (
    set s_=%%a)
  ::
  :: Display the result
  echo %s_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Set arg = WScript.Arguments 'VBS
  Wscript.Echo ShowDriveInfo(arg(0)) 'VBS
  '
  Function ShowDriveInfo(drvpath) 'VBS
    Dim fso, d, s, t 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set d = fso.GetDrive(fso.GetDriveName(fso.GetAbsolutePathName(drvpath))) 'VBS
    Select Case d.DriveType 'VBS
      Case 0: t = "Unknown" 'VBS
      Case 1: t = "Removable" 'VBS
      Case 2: t = "Fixed" 'VBS
      Case 3: t = "Network" 'VBS
      Case 4: t = "CD-ROM" 'VBS
      Case 5: t = "RAM Disk" 'VBS
    End Select 'VBS
    s = "Drive " & d.DriveLetter & ": - " & t 'VBS
    s = s & ", SN: " & Left(Hex(d.SerialNumber),4) 'VBS
    s = s & "-" & Right(Hex(d.SerialNumber),4) 'VBS
    ShowDriveInfo = s 'VBS
  End Function 'VBS

  C:\_D\TEST>cmdfaq
  Drive C: - Fixed, SN: D634-E1B2
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:42 2011
Subject: 102) How can I extract the individual bits from a decimal byte?
Date: Mon, 31 Jan 2011 01:01:42
From: ts@uwasa.fi (Timo Salmi)

   Basically this is the same task as the decimal to binary
conversion in item #32. The formulation below emphasizes extracting
each bit of a decimal byte individually. A byte contains 8 bits,
usually labeled from 0 to 7. It also shows that are many different
options to perform a task since the solution here differs
considerably from the one used in item #32.
   These bitwise operations were the key elements of programming
back in the days of Vic 20 and Commodore 64, but can still arise in
the present day as seen in the references.

  @echo off & setlocal enableextensions enabledelayedexpansion
  set decimal_=%1
  set /a b0=%decimal_% ^& 1
  set /a b1=%decimal_% ^& 2
  set /a b2=%decimal_% ^& 4
  set /a b3=%decimal_% ^& 8
  set /a b4=%decimal_% ^& 16
  set /a b5=%decimal_% ^& 32
  set /a b6=%decimal_% ^& 64
  set /a b7=%decimal_% ^& 128
  set i=-1
  for %%b in (!b0! !b1! !b2! !b3! !b4! !b5! !b6! !b7!) do (
    set bit=%%b
    set /a i+=1
    if !bit! EQU 0 (echo bit !i! = 0) else (echo bit !i! = 1)
  )
  endlocal & goto :EOF
An example of the output
  C:\_D\TEST>cmdfaq 12
  bit 0 = 0
  bit 1 = 0
  bit 2 = 1
  bit 3 = 1
  bit 4 = 0
  bit 5 = 0
  bit 6 = 0
  bit 7 = 0

Examples of bitwise operations
  @echo off & setlocal enableextensions
  set dec1_=121
  set dec2_=145
  ::
  set /a decand_=%dec1_% ^& %dec2_%
  echo %dec1_% AND %dec2_% = %decand_%
  ::
  set /a decor_=%dec1_% ^| %dec2_%
  echo %dec1_% OR  %dec2_% = %decor_%
  ::
  set /a decxor_=%dec1_% ^^ %dec2_%
  echo %dec1_% XOR %dec2_% = %decxor_%
  ::
  set /a decnot_=%dec1_% ^^ 255
  echo NOT %dec1_% = %decnot_%
  ::
  set dec3_=1
  set shft_=3
  set decshl_=%dec3_%
  set /a decshl_ ^<^<= %shft_%
  echo %dec3_% SHL %shft_% = %decshl_%
  ::
  set dec4_=128
  set shft_=1
  set decshr_=%dec4_%
  set /a decshr_ ^>^>= %shft_%
  echo %dec4_% SHR %shft_% = %decshr_%
  ::
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  121 AND 145 = 17
  121 OR  145 = 249
  121 XOR 145 = 232
  NOT 121 = 134
  1 SHL 3 = 8
  128 SHR 1 = 64
The SHL (shift left) can be used to get the powers of 2.

  @echo off & setlocal enableextensions
  set dec1_=121
  set dec2_=145
  ::
  set /a decand_=%dec1_% "&" %dec2_%
  echo %dec1_% AND %dec2_% = %decand_%
  ::
  set /a decor_=%dec1_% "|" %dec2_%
  echo %dec1_% OR %dec2_% = %decor_%
  ::
  set /a decxor_=%dec1_% "^" %dec2_%
  echo %dec1_% XOR %dec2_% = %decxor_%
  ::
  set /a decnot_=%dec1_% "^" 255
  echo NOT %dec1_% = %decnot_%
  ::
  set dec3_=1
  set shft_=3
  set decshl_=%dec3_%
  set /a decshl_ "<<"= %shft_%
  echo %dec3_% SHL %shft_% = %decshl_%
  ::
  set dec4_=128
  set shft_=1
  set decshr_=%dec4_%
  set /a decshr_ ">>"= %shft_%
  echo %dec4_% SHR %shft_% = %decshr_%
  ::
  endlocal & goto :EOF

The SET /A operations include e.g.
  ! Unary NOT operator
  & Bitwise AND
  ^ Bitwise exclusive OR
  | Bitwise OR
  %% Remainder (modulo) operator
  >> Logical shift right
  << Logical shift left

References/Comments:
 hh ntcmds.chm::/set.htm
 http://www.google.com/groups?selm=4285a523%240%2493767%24ed2619ec%40ptn-nntp-reader01.plus.net
 http://www.google.com/groups?selm=nfbd81pp3ebfjjdoqhovujsvbj1q5efn49%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:43 2011
Subject: 103) How do I exit a loop by pressing a key?
Date: Mon, 31 Jan 2011 01:01:43
From: ts@uwasa.fi (Timo Salmi)

You may wish to revisit item #14 first. Anyway:
  @echo off & setlocal enableextensions
  ::
  :: Test for CHOOSE.EXE availability at path / in the current folder
  for %%f in ("CHOOSE.EXE") do set found_=%%~$PATH:f
  if exist CHOOSE.EXE set found_=CHOOSE.EXE
  if "%found_%"=="" (
    echo CHOOSE.EXE choice.com clone not found.
    echo Available from ftp://garbo.uwasa.fi/pc/link/tscmd.zip
    goto :EOF)
  ::
  echo Press x to exit the loop
  ::
  :_loop
  set /a i_+=1
  choose /n /c:nx /tn,0 > nul
  if %errorlevel% NEQ 2 goto _loop
  ::
  echo i_=%i_% ^(cycles^)
  endlocal & goto :EOF

The output would be e.g.
  C:\_D\TEST>cmdfaq
  Press x to exit the loop
  i_=37 (cycles)
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:44 2011
Subject: 104) How can one remove double quotes from a script variable?
Date: Mon, 31 Jan 2011 01:01:44
From: ts@uwasa.fi (Timo Salmi)

There are different methods. First
  @echo off & setlocal enableextensions
  set var="a b c d"
  echo %var%
  set var=%var:"=%
  echo %var%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  "a b c d"
  a b c d
Note that ALL the quotes are removed. Also those potentially within
the string.

The other methods include
  @echo off & setlocal enableextensions
  ::
  set var="a b c d"
  echo %var%
  for %%f in (%var%) do echo %%~f
  ::
  set var="cmdfaq.*"
  echo %var%
  for %%f in (%var%) do echo %%~f
  ::
  set var=%var:"=%
  echo %var%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  "a b c d"
  a b c d
  "cmdfaq.*"
  CMDFAQ.CMD
  cmdfaq.*

Note how the asterisk * is expanded for an existing file name. In
fact, as seen in many examples, if you had
  @echo off & setlocal enableextensions
  set var="cmdfaq*.*"
  echo %var%
  for %%f in (%var%) do echo %%~ff
  endlocal & goto :EOF
the output would be something like
  C:\_D\TEST>cmdfaq
  "cmdfaq*.*"
  C:\_D\TEST\CMDFAQ THIRD.CMD
  C:\_D\TEST\CMDFAQ.CMD
  C:\_D\TEST\CMDFAQ2.CMD

Although not practical, for demonstration one can also have
  @echo off & setlocal enableextensions
  set var="a b c d"
  echo %var%
  for /f "tokens=*" %%f in ("%temp%") do set temp_=%%~sf
  echo @set var=%var%|sed -e "s/\"//g">%temp_%\tmp.cmd
  for %%c in (call del) do %%c %temp_%\tmp.cmd
  echo %var%
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  "a b c d"
  a b c d
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:45 2011
Subject: 105) How to detect whether or not a folder contains hidden files?
Date: Mon, 31 Jan 2011 01:01:45
From: ts@uwasa.fi (Timo Salmi)

As a sideline, note the usage of the caret ^ for dividing a command
structure over several lines to avoid wrapping problems in
presenting a solution.
  @echo off & setlocal enableextensions
  dir C:\MyFolder\*.* /b /a:h^
   |find /v "SomeUnlikelyString">nul^
   && set hidden_=true^
   ||set hidden_=false
  echo hidden_=%hidden_%
  endlocal & goto :EOF

The output will be either
  C:\_D\TEST>cmdfaq
  hidden_=true
or
  C:\_D\TEST>cmdfaq
  File Not Found
  hidden_=false

If you want to get rid of the "File Not Found" use the alternatives
(posted by William Allen)
  @echo off & setlocal enableextensions
  dir C:\MyFolder\*.* /a:h>nul 2>&1
  if errorlevel 1 (set hidden_=false) else (set hidden_=true)
  echo hidden_=%hidden_%
  endlocal & goto :EOF
or
  @echo off & setlocal enableextensions
  dir C:\_M\TEMP\*.* /a:h>nul 2>&1
  set hidden_=true& dir C:\MyFolder\*.* /a:h>nul 2>&1||set hidden_=false
  echo hidden_=%hidden_%
  endlocal & goto :EOF

Another option is
  @echo off & setlocal enableextensions
  attrib c:\_m\temp\*.*|findstr /b "....H">nul
  if errorlevel 1 (set hidden_=false) else (set hidden_=true)
  echo hidden_=%hidden_%
  endlocal & goto :EOF

Note how the method above can also be used e.g. for testing if a
file is read-only:
  @echo off & setlocal enableextensions
  if [%1]==[] (
    echo Usage: %~f0 [FileName]
    goto :EOF
    )
  if not exist "%~1" (
    echo File "%~1" not found
    goto :EOF
    )
  attrib "%~1"|findstr /b ".....R">nul
  if errorlevel 1 (set readonly_=false) else (set readonly_=true)
  echo File "%~1" read-only status: %readonly_%
  endlocal & goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:46 2011
Subject: 106) How to test whether a variable is a non-negative integer?
Date: Mon, 31 Jan 2011 01:01:46
From: ts@uwasa.fi (Timo Salmi)

This is one of the items which arose from a solution I needed
myself. Test for a decimal (10-base) non-negative integer. The
original solution is given after the simpler one below:
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable
  set s=%~1
  ::
  :: Do a regular expression (/r) findstr complement
  echo %s%|findstr /r "[^0-9]">nul
  if %errorlevel% GTR 0 (set isInteger=true) else (set isInteger=false)
  ::
  :: Show the result
  echo %s%
  echo isInteger=%isInteger%
  ::
  endlocal & goto :EOF
Examples of output
  C:\_D\TEST>cmdfaq 1234
  1234
  isInteger=true
or
  C:\_D\TEST>cmdfaq FF
  FF
  isInteger=false

Actually, a non-negative integer!

More fully
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable
  set s=%~1
  ::
  :: Do a regular expression (/r) findstr complement and avoid the octal trap
  echo %s%|findstr /r "[^0-9]">nul||set isDecInteger=true
  if defined isDecInteger if not "%s:~1,2%"=="" if "%s:~0,1%"=="0" set IsDecInteger=
  ::
  :: Show the result
  if defined IsDecInteger (
    echo %s% is a regular, non-negative integer
    ) else (
    echo %s% is not a regular, non-negative integer
    )
  ::
  endlocal & goto :EOF

Originaly, I had
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable
  set s=%~1
  ::
  :: Get its length, counting from zero
  set charCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set /a charCount+=1)
  set /a charCount=%charCount%-1
  ::
  :: Test that only valid characters are present
  set isInteger=true
  for /l %%c in (0,1,%charCount%) do (
    set si=!s:~%%c,1!
    echo 1234567890|findstr /l "!si!">nul
    if !errorlevel! GTR 0 set isInteger=false
    )
  ::
  :: Show the result
  echo %s%
  echo isInteger=%isInteger%
  ::
  endlocal & goto :EOF
Examples of output
  C:\_D\TEST>cmdfaq 1234
  1234
  isInteger=true
or
  C:\_D\TEST>cmdfaq FF
  FF
  isInteger=false

The solution can be expanded to other numeric or alphabetic validity
tests. For example to test if a variable is a positive decimal
number.
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable
  set s=%~1
  ::
  :: Get its length, counting from zero
  set charCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set /a charCount+=1)
  set /a charCount=%charCount%-1
  ::
  :: Test that only valid characters are present
  set isNumeric=true
  set pointCount=0
  for /l %%c in (0,1,%charCount%) do (
    set si=!s:~%%c,1!
    echo 1234567890.|findstr /l "!si!">nul
    if !errorlevel! GTR 0 set isNumeric=false
    if [!si!]==[.] set /a pointCount+=1
    )
  if %pointCount% GTR 1 set isNumeric=false
  ::
  :: Show the result
  echo %s%
  echo isNumeric=%isNumeric%
  ::
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq 12.34
  12.34
  isNumeric=true
or
  C:\_D\TEST>cmdfaq 1..
  1..
  isNumeric=false

Or, more concisely
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable
  set s=%~1
  ::
  :: Test if non-valid characters are present
  set isNumeric=true
  echo %s%|findstr "[^0-9.]">nul
  if %errorlevel% EQU 0 set isNumeric=false
  ::
  :: Count the decimal points in the variable s
  set pointCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if [!si!]==[.] set /a pointCount+=1
    )
  if %pointCount% GTR 1 set isNumeric=false
  ::
  :: Show the result
  echo %s%
  echo isNumeric=%isNumeric%
  ::
  endlocal & goto :EOF

Another example. The parameter to be given is a time parameter in
the HH:MM format. Test for its validity.
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 TimeParameterHH:MM
    goto :EOF)
  ::
  :: Test for the time parameter validity
  :: Get the parameter into a variable
  set s=%~1

  :: Get its length and count the number of colons
  set charCount=0
  set pointCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set /a charCount+=1
    if [!si!]==[:] set /a pointCount+=1
    )

  :: Test that only valid characters are present
  set isNumeric=true
  echo %s%|findstr "[^0-9:]">nul
  if %errorlevel% EQU 0 set isNumeric=false
  ::
  :: Test for the right composition
  if %pointCount% GTR 1 set isNumeric=false
  if %charCount% GTR 5 set isNumeric=false
  ::
  :: Get the components
  for /f "tokens=1,2 delims=:" %%a in ("%s%") do (
  set shour=%%a
  set sminute=%%b)
  if not defined sminute set sminute=0
  ::
  :: Test that the time is within bounds
  if %shour% GTR 23 set isNumeric=false
  if %sminute% GTR 59 set isNumeric=false
  ::
  :: Show the result
  echo s=%s%
  echo shour=%shour%
  echo sminute=%sminute%
  echo isNumeric=%isNumeric%
  ::
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq 13:58
  s=13:58
  shour=13
  sminute=58
  isNumeric=true
or
  C:\_D\TEST>cmdfaq 25:11
  s=25:11
  shour=25
  sminute=11
  isNumeric=false

References/Comments:
 http://www.google.com/groups?selm=d97av3%24mrv%241%40agate.berkeley.edu
 http://www.jsifaq.com/SF/Tips/Tip.aspx?id=9692
 http://www.google.com/groups?selm=1168700139.287904.190160%4051g2000cwl.googlegroups.com
 http://msdn.microsoft.com/en-us/library/ehs9h2x9%28VS.85%29.aspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:47 2011
Subject: 107) How to do non-trivial renaming such as IMG*.jpg to IMG_*.jpg?
Date: Mon, 31 Jan 2011 01:01:47
From: ts@uwasa.fi (Timo Salmi)

Consider the following situation
  Rename IMG1225.jpg to IMG_1225.jpg
  Rename IMG1226.jpg to IMG_1226.jpg
  Rename IMG1227.jpg to IMG_1227.jpg
  Rename IMG1228.jpg to IMG_1228.jpg

First off this can't be solved as
  ren C:\WHATEVER\IMG*.jpg IMG_*.*
since it would give you (dropping the thousands):
  IMG_225.jpg
  IMG_226.jpg
  IMG_227.jpg
  IMG_228.jpg

If you try
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%f in (C:\WHATEVER\*.jpg) do (
    rem echo %%~df%%~pf%%~nf%%~xf
    set base=%%~nf
    set base=!base:IMG=IMG_!
    ren %%~df%%~pf%%~nf%%~xf !base!%%~xf
  )
  endlocal & goto :EOF
you'll get
  IMG_1226.jpg
  IMG_1227.jpg
  IMG_1228.jpg
  IMG__1225.jpg

The cmd.exe is a command line interpreter, not a compiler. The
renaming forms a kind of a ring with the first of your files popping
up anew renamed within the execution. The solution is to use a
formulation of FOR which does not have that "bug" or "feature" in
cmd.exe.
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /f "delims=" %%f in (
    'dir /a:-d /b /s /o:n C:\WHATEVER\*.jpg') do (
    set base=%%~nf
    set base=!base:IMG=IMG_!
    ren "%%~df%%~pf%%~nf%%~xf" "!base!%%~xf"
  )
  endlocal & goto :EOF
This time you will get
  IMG_1225.jpg
  IMG_1226.jpg
  IMG_1227.jpg
  IMG_1228.jpg

Note that the above solution will recurse to subfolders, as well. If
you do not want that, use
  @echo off & setlocal enableextensions enabledelayedexpansion
  set folder_=C:\WHATEVER
  ::
  for /f "delims=" %%f in (
    'dir /a:-d /b /o:n %folder_%\*.jpg') do (
    set base=%%~nf
    set base=!base:IMG=IMG_!
    ren "%folder_%\%%~nf%%~xf" "!base!%%~xf"
  )
  endlocal & goto :EOF
The dilemma with dir /b without the /s is that %%~df and %%~pf will
not point where one would intuitively expect them to point. Instead
they point to the script's default folder. Thus the above
alternative is needed.

Incidentally, the IMG_1225.JPG format is the naming convention for
digiphotos on a Canon Ixus. It might be used on other cameras as
well, but that I know of.

Consider another, similar renaming task, which often appears as a FAQ
in slight variations. The following example recounts a true situation
which I had myself. A set of digiphotos I had needed to be renamed as
follows:
In a folder C:\_L\PHOTO
  W2010042901.JPG --> W2010042906.JPG
  W2010042902.JPG --> W2010042907.JPG
  W2010042903.JPG --> W2010042908.JPG
  :
  W2010042922.JPG --> W2010042927.JPG

The solution:
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /L %%n in (22,-1,1) do (
    set n1_=00000%%n
    set n1_=!n1_:~-2!
    set /a n2_=%%n+5
    set n2_=00000!n2_!
    set n2_=!n2_:~-2!
    echo ren C:\_L\PHOTO\W20100429!n1_!.JPG W20100429!n2_!.JPG
    )
  endlocal & goto :EOF

The (redirectable) output will be
  ren C:\_L\PHOTO\W2010042922.JPG W2010042927.JPG
  ren C:\_L\PHOTO\W2010042921.JPG W2010042926.JPG
  ren C:\_L\PHOTO\W2010042920.JPG W2010042925.JPG
  :
  ren C:\_L\PHOTO\W2010042902.JPG W2010042907.JPG
  ren C:\_L\PHOTO\W2010042901.JPG W2010042906.JPG
Observe that:
  1) The renaming is done in a reverse order.
  2) Numbers below ten need be padded with a leading zero.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:48 2011
Subject: 108) How can I execute a script one line at a time to debug it?
Date: Mon, 31 Jan 2011 01:01:48
From: ts@uwasa.fi (Timo Salmi)

Not as efficiently and conveniently than in the MS-DOS command.com
method "command /y /c". However, you can use the following obvious
construct:

  @echo off & setlocal enableextensions
  set debugon=true
  @if defined debugon echo on
  whatever
  @if defined debugon pause
  whatever
  @if defined debugon pause
  whatever
  @if defined debugon pause
  endlocal & goto :EOF

Given that you have an original script file myscript.cmd which you
wish to debug by stepping through it one line at a time, the next
question is how do you easily insert the debug lines without
disturbing the original. Essentially, use the following G(nu)AWK
command on the command line
  gawk "{printf \"%s\n@if defined debugon pause\n\",$0}" myscript.cmd>mydebug.cmd
Before using, you may have "manually" to see to the lines
  set debugon=true
  @if defined debugon echo on

The advantage of the "@if defined debugon pause" is that you can
customize your debugging by inserting such lines only where of
essence. It usually is not necessary to have it on every second
line.

You can make the debugging a bit more informative e.g. as follows
  @echo off & setlocal enableextensions
  set debugon=true
  whatever
  call :BreakPoint 1
  whatever
  call :BreakPoint 2
  whatever
  call :BreakPoint "3 %time%"
  endlocal & goto :EOF
  ::
  :BreakPoint
  if not defined debugon goto :EOF
  setlocal
  if not "%~1"=="" echo Debugmode breakpoint %~1
  set /p ask_="Press Enter to continue . . . "
  endlocal & goto :EOF

The output might be something like
  C:\_M>C:\_D\TEST\CMDFAQ.CMD
  whatever
  Debugmode breakpoint 1
  Press Enter to continue . . .
  whatever
  Debugmode breakpoint 2
  Press Enter to continue . . .
  whatever
  Debugmode breakpoint 3 13:50:35.99
  Press Enter to continue . . .
  C:\_M>
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:49 2011
Subject: 109) How do I open e.g. three separate instances of notepad at one go?
Date: Mon, 31 Jan 2011 01:01:49
From: ts@uwasa.fi (Timo Salmi)

> I have a file OPENTEXT.CMD that contains the following lines:
>  notepad textfile1.txt
>  notepad textfile2.txt
>  notepad textfile3.txt
> When I type OPENTEXT, I want all three of the text files to open in
> separate Notepad windows.

START starts a separate window to run a specified program or
command.
  @echo off & setlocal enableextensions
  start "" notepad textfile1.txt
  start "" notepad textfile2.txt
  start "" notepad textfile3.txt
  endlocal & goto :EOF

start ["title"] ...
"title": Specifies the title to display in Command Prompt window title bar.
It always is advisable to include it, even if left empty (a common practice).

Also see item #36.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:50 2011
Subject: 110) Can I use a script to determine if a specific printer exists?
Date: Mon, 31 Jan 2011 01:01:50
From: ts@uwasa.fi (Timo Salmi)

Let's start with displaying the default printer
  @echo off & setlocal enableextensions
  cscript C:\WINDOWS\system32\prnmngr.vbs -g
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  The default printer is HP home DeskJet 500

To list all of the printers for a computer
  @echo off & setlocal enableextensions
  cscript C:\WINDOWS\system32\prnmngr.vbs -l
  endlocal & goto :EOF

If the computer is on a network, for a specific printer one could try
for example
  @echo off & setlocal enableextensions
  set find_=HP DeskJet 895Cxi
  net view \\%COMPUTERNAME%^
    |findstr /c:"Print "^
    |findstr /c:" %find_% ">nul
  if %errorlevel% EQU 0 (
    echo Found %find_%
    ) else (
    echo Did not find %find_%)
  endlocal & goto :EOF
The output would be e.g.
  C:\_D\TEST>cmdfaq
  Found HP DeskJet 895Cxi

The carets (^) in the code are used to divide a long command on
multiple lines.

References/Comments:
  hh ntcmds.chm::/net_view.htm
  hh ntcmds.chm::/findstr.htm
  http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/prnmngr.mspx?mfr=true
  http://technet.microsoft.com/en-us/library/bb490974.aspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:51 2011
Subject: 111) How can I detect if a folder is shared or not?
Date: Mon, 31 Jan 2011 01:01:51
From: ts@uwasa.fi (Timo Salmi)

The same method as in the previous item can be used e.g. to check if
a folder is shared or not.
  @echo off & setlocal enableextensions
  set find_=C:\_M
  net share|find /i "%find_% ">nul
  if %errorlevel% EQU 0 (
    echo Folder "%find_%" is shared
    ) else (
    echo Folder "%find_%" is not shared or does not exist)
  endlocal & goto :EOF

References/Comments:
  http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/net_share.mspx?mfr=true
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:52 2011
Subject: 112) Help, an old program fails to run since I have no floppy drive.
Date: Mon, 31 Jan 2011 01:01:52
From: ts@uwasa.fi (Timo Salmi)

 Q: I am trying trun an old program. But it fails since the program
requires a disk present in the floppy drive A: which I do not have.

 A: This trick sometimes works if the old program just wants to have
a floppy present to write to
  @echo off & setlocal enableextensions
  mkdir C:\_A
  subst A: C:\_A
  TheProgram
  subst /d A:
  rmdir C:\_A
  endlocal & goto :EOF

References/Comments:
  hh ntcmds.chm::/ntcmds.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:53 2011
Subject: 113) How do I find all *.TXT files on the C: drive sorted by size?
Date: Mon, 31 Jan 2011 01:01:53
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions enabledelayedexpansion
  if exist "%temp%\temp.dir" del "%temp%\temp.dir"
  for /f "delims=" %%f in (
    'dir /a:-d /b /s c:\*.txt') do (
    set filename_="%%~ff"
    set filesize_=0000000000%%~zf
    set filesize_=!filesize_:~-10!
    echo !filesize_! !filename_! >>"%temp%\temp.dir"
    )
  sort /r "%temp%\temp.dir"
  if exist "%temp%\temp.dir" del "%temp%\temp.dir"
  endlocal & goto :EOF

The output might start with something like
 0000401272 "c:\INF2\FAQPAS.TXT"
 0000389257 "c:\BAT\1BATFAQ.TXT"
 0000359101 "c:\CHYDE\INDEX.TXT"
 0000272243 "c:\CMD\1CMDFAQ.TXT"

Should one wish to get rid of the leading filesize:
  @echo off & setlocal enableextensions enabledelayedexpansion
  if exist "%temp%\temp.dir" del "%temp%\temp.dir"
  for /f "delims=" %%f in (
    'dir /a:-d /b /s c:\*.txt') do (
    set filename_="%%~ff"
    set filesize_=0000000000%%~zf
    set filesize_=!filesize_:~-10!
    echo !filesize_! !filename_! >>"%temp%\temp.dir"
    )
  ::
  for /f "delims=" %%a in ('sort /r "%temp%\temp.dir"') do (
    set filename_=%%a
    set filename_=!filename_:~11!
    echo !filename_!
    )
  ::
  if exist "%temp%\temp.dir" del "%temp%\temp.dir"
  endlocal & goto :EOF

Then the output would be something like
"c:\_F\INF2\FAQPAS.TXT"
"c:\_F\BAT\1BATFAQ.TXT"
"c:\_F\CHYDE\INDEX.TXT"
"c:\_F\CMD\1CMDFAQ.TXT"


Consider again the first solution code. The problem with that solution
is that file names with exclamation marks (!) get dropped because of
the enabled delayedexpansion. To counter that problem use a subroutine
  @echo off & setlocal enableextensions disabledelayedexpansion
  set tempdir_=%temp%\temp.dir
  if exist "%tempdir_%" del "%tempdir_%"
  for /f "delims=" %%f in (
    'dir /a:-d /b /s c:\*.txt') do (
    call :NameSizeToTemp "%%~ff"
    )
  sort /r "%tempdir_%"
  if exist "%tempdir_%" del "%tempdir_%"
  endlocal & goto :EOF
  ::
  :NameSizeToTemp
  set filename_="%~f1"
  set filesize_=0000000000%~z1
  set filesize_=%filesize_:~-10%
  echo %filesize_% %filename_% >>"%tempdir_%"
  goto :EOF

The above could also be written as
  @echo off & setlocal enableextensions disabledelayedexpansion
  set tempdir_=%temp%\temp.dir
  if exist "%tempdir_%" del "%tempdir_%"
  for /r "C:\" %%f in ("*.TXT") do call :NameSizeToTemp "%%~ff"
  sort /r "%tempdir_%"
  if exist "%tempdir_%" del "%tempdir_%"
  endlocal & goto :EOF
  ::
  :NameSizeToTemp
  set filename_="%~f1"
  set filesize_=0000000000%~z1
  set filesize_=%filesize_:~-10%
  echo %filesize_% %filename_% >>"%tempdir_%"
  goto :EOF
A small part of the output might look something like
  :
  0000123770 "C:\MAIL\BIKES.TXT"
  0000112198 "C:\ACCOUNTS\FEB2008.TXT"
  0000108029 "C:\TEACH\PARAG\ACCLAW.TXT"
  :
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:54 2011
Subject: 114) How do I pick a file's lines that are three characters long?
Date: Mon, 31 Jan 2011 01:01:54
From: ts@uwasa.fi (Timo Salmi)

The method is an adaptation of items #26 and #27 of this FAQ.
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /f "delims=" %%a in ('type myfile.txt') do (
    set name_=%%a
    set charCount=0
    for /l %%c in (0,1,255) do (
      set si=!name_:~%%c,1!
      if defined si set /a charCount+=1)
    if !charCount! EQU 3 echo !name_!
    )
  endlocal & goto :EOF
This method cannot handle names with the "poison characters".

However, a much simpler and still an all-script solution is
  findstr "^...$" "My test file.txt"

With sed it would be
  <"My test file.txt" sed -n "s/^...$/&/p"

Note the redirection formulation instead of using
  sed -n "s/^...$/&/p" "My test file.txt"
which may fail depending on the SED port version LFN handling.

With gawk
  <"My test file.txt" gawk "{if(length()==3)printf\"%%s\n\",$0}"

What if you want all the names that are three or less characters long?
  findstr "^.$ ^..$ ^...$" "My test file.txt"

References/Comments:
  hh ntcmds.chm::/findstr.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:55 2011
Subject: 115) How can I decompose the path to be one folder per line?
Date: Mon, 31 Jan 2011 01:01:55
From: ts@uwasa.fi (Timo Salmi)

With G(nu)AWK
  @echo off & setlocal enableextensions
  echo %path%;^
    |gawk -F; "{for (i=1;i<=NF-1;++i) printf \"%%s\n\",$i}"
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  c:\_f\xtools
  c:\_f\tools
  c:\_f\ftools
  c:\_e\arczip
  C:\WINDOWS\system32
  C:\WINDOWS
  C:\WINDOWS\System32\Wbem
  C:\Program Files\TSEPro
  C:\Program Files\010Editor
  C:\Program Files\QuickTime\QTSystem\
  C:\Program Files\SSH Communications Security\SSH Secure Shell

With SED
  path | sed -e s/.*=// -e s/;/\r\n/g

Or with straight script
  @echo off & setlocal enableextensions
  for /f "tokens=1-15 delims=;" %%a in ("%path%") do (
    if not [%%a]==[] echo %%a
    if not [%%b]==[] echo %%b
    if not [%%c]==[] echo %%c
    if not [%%d]==[] echo %%d
    if not [%%e]==[] echo %%e
    if not [%%f]==[] echo %%f
    if not [%%g]==[] echo %%g
    if not [%%h]==[] echo %%h
    if not [%%i]==[] echo %%i
    if not [%%j]==[] echo %%j
    if not [%%k]==[] echo %%k
    if not [%%l]==[] echo %%l
    if not [%%m]==[] echo %%m
    if not [%%n]==[] echo %%n
    if not [%%o]==[] echo %%o
    )
  endlocal & goto :EOF

Exceptionally for this FAQ a pure Visual Basic Scripting (i.e a non-
batch aided solution) is of particular relevance because the
environment in a CLI might differ (you may have added some folders or
other customized the path, as I have done). The VBS solution gives
your regular path.

  ' SHOWPATH.VBS by Prof. Timo Salmi
  ' Last modified Wed 11-Jun-2008
  '
  Sub GetAndShowPath()
    dim s, n, m, myPath, rest
    Set WshShell = WScript.CreateObject("WScript.Shell")
    Set WshSysEnv = WshShell.Environment("SYSTEM")
    myPath=WshSysEnv("PATH")
    m = 1
    n = 1
    rest = myPath & ";"
    Do While n > 0
      n = Instr(1,rest,";")
      if n = 0 Then Exit Do
      s = s & Mid(rest,1,n-1) & vbCrLf
      m = n + 1
      rest = Mid(rest,m)
    Loop
    WScript.Echo s & vbCrLf & myPath
  End Sub 'GetAndShowPath
  '
  Sub MainProgram()
    GetAndShowPath
  End Sub 'MainProgram
  '
  MainProgram

References/Comments:
 http://www.google.com/groups?selm=4321fd74%240%2417479%24ed2e19e4%40ptn-nntp-reader04.plus.net
 http://www.google.com/groups?selm=ha54i15ju5b3ek2qhj4c33cd0qplhmhc6u%404ax.com
 http://www.google.com/groups?selm=uatXKdCm5DODFwTL%40merlyn.demon.co.uk
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:56 2011
Subject: 116) How do I get a list all the *.BAT files which are at path?
Date: Mon, 31 Jan 2011 01:01:56
From: ts@uwasa.fi (Timo Salmi)

Expanding on the solution given in the second link in the
"References/Comments:" of the previous item we can e.g. list all the
*.BAT files appearing at the path:
  @echo off & setlocal enableextensions
  for %%a in ("%path:;=" "%") do (
    for /f %%f in ('dir /b /a:-d /o:n "%%~a\*.bat"') do (
      echo %%~a\%%f)
    )>>"%temp%\temp.dir"
  for %%c in (type del) do call %%c "%temp%\temp.dir"
  endlocal & goto :EOF

There is, however an even better solution which avoids the "File not
found" problem for folders that contain no *.BAT files. The snippet
is from the reference at the end of this item.
  @echo off & setlocal enableextensions
  for %%a in ("%path:;=" "%") do (
    for %%g in ("%%~a\*.bat") do echo %%~fg)
  endlocal & goto :EOF

A tangent question of a Unix "which" done with script commands is
covered in item #46.

References/Comments:
  http://www.google.com/groups?selm=ha54i15ju5b3ek2qhj4c33cd0qplhmhc6u%404ax.com
  http://www.google.com/groups?selm=m2k4i1luek2th2087u045sasa1n112dhlf%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:57 2011
Subject: 117) Is it possible to get the physical memory from the cmd?
Date: Mon, 31 Jan 2011 01:01:57
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  for /f "tokens=4,5" %%a in (
    'systeminfo^|find "Total Physical Memory"') do (
    set memory_=%%a
    set units_=%%b)
  echo Memory = %memory_% %units_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  Memory = 511 MB
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:58 2011
Subject: 118) How to handle irregular empty fields of a CSV file?
Date: Mon, 31 Jan 2011 01:01:58
From: ts@uwasa.fi (Timo Salmi)

This comes out of a real-life production script problem I had
myself. The CSV (Comma Separated Values) file format is useful for
many tasks because of its relation to Excel. Consider the following,
simple example CSV file myfile.csv (mimics one common address book
format)

  a11,a12,a13
  a21,,a23

The script
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /f "tokens=1-3 delims=," %%a in ('type "myfile.csv"') do (
    set s1_=%%a
    set s2_=%%b
    set s3_=%%c
    if defined s1_ (echo !s1_!) else (echo ..)
    if defined s2_ (echo !s2_!) else (echo ..)
    if defined s3_ (echo !s3_!) else (echo ..)
    )
  endlocal & goto :EOF

will produce
  a11
  a12
  a13
  a21
  a23
  ..

The .. line obviously is mislocated.

Is there a way out? One option is inserting a "-" within the empty ,,
pair before going through the file

  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Make a demonstration test file
  echo a11,a12,a13>"mytest.csv"
  echo a21,,a23>>"mytest.csv"
  ::
  :: The actual routine
  for /f "delims=" %%a in ('type "mytest.csv"') do (
    set s_=%%a
    set s_=!s_:,,=,-,!
    set s_=!s_:,,=,-,!
    for /f "tokens=1-3 delims=," %%a in ("!s_!") do (
      set s1_=%%a
      set s2_=%%b
      set s3_=%%c
      if not [!s1_!]==[-] (echo !s1_!) else (echo ..)
      if not [!s2_!]==[-] (echo !s2_!) else (echo ..)
      if not [!s3_!]==[-] (echo !s3_!) else (echo ..)
      )
    )
  ::
  :: Clean up
  for %%f in ("mytest.csv") do if exist %%f del %%f
  endlocal & goto :EOF

Now the output is the more logical
  a11
  a12
  a13
  a21
  ..
  a23

There is a subtle catch. Performing the substitution twice in the
script above is not a mistake. It is required since in the more
generic case where can be either an odd or and even number of
adjacent ,, pairs. Ensuring the substitution globally takes two
passes. This is not only script-related. Even any text editor or SED
requires the same.

Also a Visual Basic Script (VBScript) aided solution can be used
  @echo off & setlocal enableextensions
  ::
  :: Make a demonstration test file
  echo a11,a12,a13>"mytest.csv"
  echo a21,,a23>>"mytest.csv"
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" < "mytest.csv"
  ::
  :: Clean up
  for %%f in ("%vbs_%" "mytest.csv") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '.............................................
  'The Visual Basic Script
  '
  Do While Not WScript.StdIn.AtEndOfStream  'VBS
    str = WScript.StdIn.ReadLine            'VBS
    str = str + ","                         'VBS
    str = Replace (str, ",,",",-,")         'VBS
    str = Replace (str, ",,",",-,")         'VBS
    '
    p1 = Instr (1, str, ",", 1)             'VBS
    str1 = Mid (str, 1, p1-1)               'VBS
    If str1 <> "-" Then                     'VBS
      WScript.StdOut.WriteLine str1         'VBS
      Else                                  'VBS
      WScript.StdOut.WriteLine ".."         'VBS
    End If                                  'VBS
    '
    p2 = Instr (p1+1, str, ",", 1)          'VBS
    str2 = Mid (str, p1+1, p2-p1-1)         'VBS
    If str2 <> "-" Then                     'VBS
      WScript.StdOut.WriteLine str2         'VBS
      Else                                  'VBS
      WScript.StdOut.WriteLine ".."         'VBS
    End If                                  'VBS
    '
    p3 = Instr (p2+1, str, ",", 1)          'VBS
    str3 = Mid (str, p2+1, p3-p2-1)         'VBS
    If str3 <> "-" Then                     'VBS
      WScript.StdOut.WriteLine str3         'VBS
      Else                                  'VBS
      WScript.StdOut.WriteLine ".."         'VBS
    End If                                  'VBS
    '
    WScript.StdOut.WriteLine                'VBS
  Loop                                      'VBS

The output will be
  C:\_D\TEST>cmdfaq
  a11
  a12
  a13

  a21
  ..
  a23

References/Comments:
 http://www.google.com/groups?selm=dh2mr6%24cer%241%40haavi.uwasa.fi
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:01:59 2011
Subject: 119) How can I remove any leading zeros from an unsigned integer?
Date: Mon, 31 Jan 2011 01:01:59
From: ts@uwasa.fi (Timo Salmi)

First try the following and you'll see why this can be important
  @echo off & setlocal enableextensions
  set s_=008
  set /a s_=%s_%+2
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  Invalid number.  Numeric constants are either decimal (17),
  hexadecimal (0x11), or octal (021).

To remove the leading zeros (and leading spaces)
  @echo off & setlocal enableextensions
  set s_= 008
  echo %s_%
  echo %s_%|findstr [123456789]>nul
  if %errorlevel% EQU 0 (
    for /f "tokens=* delims=0 " %%a in ('echo %s_%') do (
      set s_=%%a)
    ) else (set s_=0)
  echo %s_%
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
   008
  8

or, slightly simpler
  @echo off & setlocal enableextensions
  set s_= 0092010
  echo %s_%
  if %s_% EQU 0 set s_=0
  for /f "tokens=* delims=0 " %%a in ('echo %s_%') do set s_=%%a
  echo %s_%
  endlocal & goto :EOF
The output is
  C:\_D\TEST>cmdfaq
   0092010
  92010

Or, using a subroutine method
  @echo off & setlocal enableextensions
  set s_=000
  echo %s_%
  call :TrimZeros "%s_%" s_
  echo %s_%
  endlocal & goto :EOF
  ::
  :: =============================================
  :TrimZeros Dymmy1 Return_
  setlocal enableextensions
  echo %~1|findstr [a-zA-Z\.]>nul
  if %errorlevel% EQU 0 (endlocal & set "%2=Error" & goto :EOF)
  echo %1|findstr [123456789]>nul
  if %errorlevel% EQU 0 (
    for /f "tokens=* delims=0 " %%a in ('echo %~1') do (
      set Return_=%%a)
    ) else (set Return_=0)
  endlocal & set "%2=%Return_%" & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  000
  0

Another solution
  @echo off & setlocal enableextensions
  set s_=009
  echo %s_%
  :loop
  if not "%s_%"=="0" if "%s_:~0,1%"=="0" set s_=%s_:~1%&goto loop
  echo %s_%
  endlocal & goto :EOF

Alternatively one could use
  SET N=009
  SET /a N=1%N%-(11%N%-1%N%)/10
  ECHO N=%N%
The output will be
  N=9

The problem can also be solved with a Visual Basic Script (VBScript).
Consider
  @echo off & setlocal enableextensions
  set s_= 0080
  echo %s_%
  >"%temp%\tmp$$$.vbs" echo WScript.Echo CLng(%s_%)
  for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set s_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  echo %s_%
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
   0080
  80

References/Comments:
 http://www.google.com/groups?selm=dhdijc%24s5c%241%40haavi.uwasa.fi
 http://www.google.com/groups?selm=1gkwlj8n0alij.uq6pg3ueldok.dlg%4040tude.net
 http://www.google.com/groups?selm=433a8072%241_5%40alt.athenanews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:00 2011
Subject: 120) How do I use AND/OR/XOR/NOT operators in an IF statement?
Date: Mon, 31 Jan 2011 01:02:00
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  if [%2]==[] (
    echo Usage %~dpn0 var1 var2
    goto :EOF)
  set var1=%~1
  set var2=%~2
  ::
  if "%var1%"=="Timo" if "%var2%"=="Salmi" echo Timo AND Salmi
  ::
  set or_=
  if "%var1%"=="Timo" set or_=true
  if "%var2%"=="Salmi" set or_=true
  if defined or_ echo Timo OR Salmi
  ::
  set xor_=
  if "%var1%"=="Timo" set xor_=true
  if "%var2%"=="Salmi" set xor_=true
  if "%var1%"=="Timo" if "%var2%"=="Salmi" set xor_=
  if defined xor_ echo Timo XOR Salmi
  ::
  if not "%var1%"=="Timo" echo Not Timo
  if not "%var2%"=="Salmi" echo Not Salmi
  ::
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq Timo Salmi
  Timo AND Salmi
  Timo OR Salmi

  C:\_D\TEST>cmdfaq Timo testing
  Timo OR Salmi
  Timo XOR Salmi
  Not Salmi

  C:\_D\TEST>cmdfaq Still testing
  Not Timo
  Not Salmi

Alternatively, the OR test could be written as
  set or_=true
  if not "%var1%"=="Timo" if not "%var2%"=="Salmi" set or_=
  if defined or_ (echo Timo OR Salmi) else (echo Neither)

Yet another way of testing an OR condition
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage %~dpn0 var1
    goto :EOF)
  ::
  echo %~1|findstr /c:"Timo" /c:"Salmi">nul&&echo Timo OR Salmi||echo Neither
  endlocal & goto :EOF

The output might be
  C:\_D\TEST>cmdfaq Timo
  Timo OR Salmi
or
  C:\_D\TEST>cmdfaq Foo
  Neither

Consider a variation of the task. If you have two variables (var1 and
var2) test whether either (or both) have the value "Timo".
  @echo off & setlocal enableextensions
  if [%2]==[] (
    echo Usage %~dpn0 var1 var2
    goto :EOF)
  set var1=%~1
  set var2=%~2
  ::
  set or_=
  for %%a in ("%var1%" "%var2%") do if %%a=="Timo" set or_=true
  if defined or_ (echo Timo was found) else (echo Timo was not found)
  endlocal & goto :EOF

The output might be
  C:\_D\TEST>cmdfaq Timo Salmi
  Timo was found

Also see item #102 "How can I extract the individual bits from a
decimal byte?"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:01 2011
Subject: 121) How do I make a simple reminder to pop up on the desktop?
Date: Mon, 31 Jan 2011 01:02:01
From: ts@uwasa.fi (Timo Salmi)

Below is a simplified version. Only one rendition can be running at
a time. A somewhat more comprehensive version, with multiple calls
allowed, is included in this FAQ collection as WAKEUP.CMD

  @echo off & setlocal enableextensions
  ::
  echo First customize the two instances of C:\_M\TEMP\wakeup.vbs
  echo And remove the first two echo lines and the first goto :EOF
  goto :EOF
  ::
  :: Usage
  if [%1]==[] (
    echo.
    echo Usage: %~f0 [HH:MM]
    echo No error checking
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=C:\_M\TEMP\wakeup.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the Visual Basic Script
  at %1 /interactive "%vbs_%"
  at
  endlocal & goto :EOF
  '
  '.............................................
  'The Visual Basic Script
  '
  Dim WshShell, fso                                                        'VBS
  Set WshShell = WScript.CreateObject("WScript.Shell")                     'VBS
  Set fso = CreateObject("Scripting.FileSystemObject")                     'VBS
  WshShell.Run "sndrec32 /play /close C:\WINDOWS\Media\tada.wav", 2, false 'VBS
  WScript.Echo "Time to wake up"                                           'VBS
  fso.DeleteFile("C:\_M\TEMP\wakeup.vbs")                                  'VBS


A slightly edited example of the immediate output. For more on the
"at" usage apply AT /?
  C:\_D\TEST>cmdfaq 06:15
  Added a new job with job ID = 1
  Status ID   Day         Time    Command Line
          1   Today       06:15   C:\_M\TEMP\wakeup.vbs

The actual output on the desktop looks something like this
       +--------------------------+
       |  Windows Script Host [X] |
       |--------------------------|
       |                          |
       |  Time to wake up         |
       |                          |
       |     +----------+         |
       |     |    OK    |         |
       |     +----------+         |
       +--------------------------+

Should you wish to cancel the above job before it is executed apply
"AT 1 /delete".

References/Comments:
  hh ntcmds.chm::/at.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:02 2011
Subject: 122) How to list files present in folder A but not in folder B?
Date: Mon, 31 Jan 2011 01:02:02
From: ts@uwasa.fi (Timo Salmi)

> I have a folder (Folder A) that has 11,156 files in it.  I have a
> second folder (Folder B) that has 11,121 files in it. I want to
> generate a list of the files that exist in Folder A but not in B.
> How can I do this?

If you have the UNIX port egrep.exe then it is fairly simple:

  @echo off & setlocal enableextensions
  set folder1_=WhateverA
  set folder2_=WhateverB
  dir /b "%folder1_%">"%temp%\fold1.dir"
  dir /b "%folder2_%">"%temp%\fold2.dir"
  ::
  egrep -v -f "%temp%\fold2.dir" "%temp%\fold1.dir"
  ::
  for %%f in ("%temp%\fold*.dir") do if exist %%f del %%f
  endlocal & goto :EOF

The output might be something like
  C:\_D\TEST>cmdfaq
  BATFAQ.BAS
  BATFAQ.BAT
  BATFAQ2.BAT
  BATFAQ3.BAT
  CMDFAQ2.CMD

With the natural exception of the first and the last line the above
solution is also MS-DOS+Win../95/98/Me compliant.

The task can also be solved with pure script, as below. The solution
below has been expanded to include both the NOT and AND cases.

  @echo off & setlocal enableextensions enabledelayedexpansion
  set folder1_=C:\_D\TEST
  set folder2_=C:\_L\TODAY
  ::
  echo.
  echo Files that exist in %folder1_%
  echo but not in %folder2_%
  echo.
  for %%f in ("%folder1_%\*.*") do (
    if not exist "%folder2_%\%%~nxf" (
    set filename_=%%~dpnxf
    set filedate_=%%~tf
    set filesize_=          %%~zf
    set filesize_=!filesize_:~-10!
    echo !filedate_! !filesize_! !filename_!))
  ::
  echo.
  echo Files that exist in %folder1_%
  echo AND in %folder2_%
  echo.
  for %%f in ("%folder1_%\*.*") do (
    if exist "%folder2_%\%%~nxf" (
      set filename_=%%~dpnxf
      set filedate_=%%~tf
      set filesize_=          %%~zf
      set filesize_=!filesize_:~-10!
      echo !filedate_! !filesize_! !filename_!
      ::
      set filename2_=%folder2_%\%%~nxf
      for %%g in ("!filename2_!") do (
        set filename_=%%~dpnxg
        set filedate_=%%~tg
        set filesize_=          %%~zg
        set filesize_=!filesize_:~-10!
        echo !filedate_! !filesize_! !filename_!)
      echo.
      )
    )
  ::
  endlocal & goto :EOF

The output might be something like

  C:\_D\TEST>cmdfaq

  Files that exist in C:\_D\TEST
  but not in C:\_L\TODAY

  19.02.2005 12:52         50 C:\_D\TEST\BATFAQ.BAS
  21.04.2005 00:29        824 C:\_D\TEST\BATFAQ.BAT
  17.04.2005 11:52      21928 C:\_D\TEST\BATFAQ2.BAT
  03.12.2002 07:58         90 C:\_D\TEST\BATFAQ3.BAT
  14.10.2005 17:40      12001 C:\_D\TEST\CMDFAQ2.CMD

  Files that exist in C:\_D\TEST
  AND in C:\_L\TODAY

  29.10.2005 06:58       1255 C:\_D\TEST\CMDFAQ.CMD
  28.10.2005 22:16        317 C:\_L\TODAY\CMDFAQ.CMD
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:03 2011
Subject: 123) How to test if a file is in a folder or below two or more times?
Date: Mon, 31 Jan 2011 01:02:03
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions enabledelayedexpansion
  set startat_=C:\_M
  set filename_=temp48.prn
  ::
  set count_=0
  for /f %%f in ('dir /b /s "%startat_%\%filename_%"') do (
    set /a count_+=1)
  ::
  echo Found %count_% occurrences of %filename_%
  if %count_% GTR 1 (
    for /f %%f in ('dir /b /s "%startat_%\%filename_%"') do (
      set filename_=%%~dpnxf
      set filedate_=%%~tf
      set filesize_=          %%~zf
      set filesize_=!filesize_:~-10!
      echo !filedate_! !filesize_! !filename_!))
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  Found 2 occurrences of temp48.prn
  29.10.2005 07:35       1705 C:\_M\temp48.prn
  29.10.2005 07:35       1705 C:\_M\TEMP\TEMP48.PRN

There is a catch, however. Since enabledelayedexpansion has been
applied, the file names with exclamation marks would miss the
exclamation mark! To circumvent this dilemma, use a subroutine call
instead.
  @echo off & setlocal enableextensions
  set startat_=C:\_M
  set filename_=temp48.prn
  ::
  set count_=0
  for /f %%f in ('dir /b /s "%startat_%\%filename_%"') do (
    set /a count_+=1)
  ::
  echo Found %count_% occurrences of %filename_%
  if %count_% GTR 1 (
    for /f %%f in ('
      dir /b /s "%startat_%\%filename_%"') do (
        call :ShowInfo "%%~ff"))
  endlocal & goto :EOF
  ::
  :: =======================================================
  :ShowInfo
  setlocal enableextensions disabledelayedexpansion
    set filename_=%~dpnx1
    set filedate_=%~t1
    set filesize_= %~z1
    set filesize_=%filesize_:~-10%
    echo %filedate_% %filesize_% %filename_%
  endlocal & goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:04 2011
Subject: 124) How do I find files which do NOT contain the search string?
Date: Mon, 31 Jan 2011 01:02:04
From: ts@uwasa.fi (Timo Salmi)

Incidentally, this task arose from my own need to check through a
number of html files which I had to edit. I wanted to see if I
missed making one of the intended adjustments.

  @echo off & setlocal enableextensions enabledelayedexpansion
  echo +---------------------------------------------------+
  echo ^| NOFIND.CMD Find files not containing a string     ^|
  echo ^| By Prof. Timo Salmi, Last modified Sun 6-Nov-2005 ^|
  echo +---------------------------------------------------+
  echo.
  ::
  :: Set the appropriate variables
  set string_=%~1
  set source_=%~2
  set ignore_=%~3
  set help_=
  ::
  :: Syntax help, if necessary
  if not defined source_ set help_=true
  if defined ignore_ (
    if /i not "%~3"=="/i" set help_=true
  )
  if defined help_ (
    echo Usage: %~0 "string" "[[drive:][path]filename]" [/i]
    echo Wildcards allowed
    echo Search also subfolders implicitly assumed
    goto :EOF)
  ::
  :: Do the nofind recursively
  for /f %%f in ('dir /b /s "%source_%"') do (
    set file_=%%~dpnxf
    find %ignore_% "%string_%" "!file_!">nul
    if !errorlevel! NEQ 0 echo !file_!
  )
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=436d9c6d%241_2%40alt.athenanews.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:05 2011
Subject: 125) How do I get the age of a file? Or of the files in a folder?
Date: Mon, 31 Jan 2011 01:02:05
From: ts@uwasa.fi (Timo Salmi)

Although the ingredients of this task already are covered in this FAQ
(in particular see item #31 and item #45), let's revisit this frequent
question. First consider the case of a single file:
  @echo off & setlocal enableextensions
  ::
  :: Usage
  if "%~1"=="" (
    echo Usage: %~0 ["Filename"]
    goto :EOF)
  ::
  :: Check for existence
  if not exist "%~1" (
    echo Target "%~1" not found
    goto :EOF)
  ::
  :: Temporary files
  set vbs_=%temp%\tmp$$$.vbs
  set tmp_=%temp%\tmp$$$.cmd
  ::
  :: Build a Visual Basic Script
  > "%vbs_%" echo Set FSO=CreateObject("Scripting.FileSystemObject")
  >>"%vbs_%" echo sysDate = Date
  >>"%vbs_%" echo Set fname = FSO.GetFile("%~1")
  >>"%vbs_%" echo age = DateDiff("d", fname.DateLastModified, SysDate)
  >>"%vbs_%" echo WScript.Echo "@set age_=" ^& age
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" > "%tmp_%"
  ::
  :: Run the auxiliary cmd script made by vbs
  call %tmp_%
  ::
  :: Display the result
  echo The file "%~1"
  echo is %age_% days old
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq cmdfaq2.cmd
  The file "cmdfaq2.cmd"
  is 14 days old

An aside. The above script fails if given an existing folder as the
parameter instead of a proper file name. How to test for the type
(folder or file) is covered in item #75 if you find it relevant to
include that test.

Next consider traversing all the files in a folder
  @echo off & setlocal enableextensions
  ::
  :: Usage
  if "%~1"=="" (
    echo Usage: %~0 ["[Folder\]FileName"]
    echo Wilcards allowed in the filename
    goto :EOF)
  ::
  :: Traverse an entire folder
  if "%~2"=="recurse" goto _next
  for %%f in ("%~1") do call "%~0" "%%~f" recurse
  goto :EOF
  ::
  :_next
  ::
  :: Temporary files
  set vbs_=%temp%\tmp$$$.vbs
  set tmp_=%temp%\tmp$$$.cmd
  ::
  :: Build a Visual Basic Script
  > "%vbs_%" echo Set FSO=CreateObject("Scripting.FileSystemObject")
  >>"%vbs_%" echo sysDate = Date
  >>"%vbs_%" echo Set fname = FSO.GetFile("%~1")
  >>"%vbs_%" echo age = DateDiff("d", fname.DateLastModified, SysDate)
  >>"%vbs_%" echo WScript.Echo "@set age_=" ^& age
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" > "%tmp_%"
  ::
  :: Run the auxiliary cmd script made by vbs
  call "%tmp_%"
  ::
  :: Display the result
  echo The file "%~1"
  echo is %age_% days old
  ::
  :: Clean up
  for %%f in ("%vbs_%" "%tmp_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq "c:\_d\test\*.*"
  The file "c:\_d\test\BATFAQ.BAS"
  is 271 days old
  The file "c:\_d\test\BATFAQ.BAT"
  is 211 days old
  The file "c:\_d\test\BATFAQ2.BAT"
  is 214 days old
  The file "c:\_d\test\BATFAQ3.BAT"
  is 1080 days old
  The file "c:\_d\test\CMDFAQ.CMD"
  is 0 days old
  The file "c:\_d\test\CMDFAQ2.CMD"
  is 14 days old

Finally, what about pinpointing the files that are for example at
least 250 days old? A small modification suffices:
  ::
  :: Display the result
  if %age_% GEQ 250 (
    echo The file "%~1"
    echo is %age_% days old
    )

It is trivial to see that you can put any operation in there. One
very frequently asked questions is "How do I delete files older than
x days with a command line script?". Just insert within the "if"
  del /p "%~1"

References/Comments:
 http://groups.google.com/groups?as_ugroup=alt.msdos.batch.nt&as_q=Remove+files+older+than+X+days
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:06 2011
Subject: 126) How do I grep for a line with a tab?
Date: Mon, 31 Jan 2011 01:02:06
From: ts@uwasa.fi (Timo Salmi)

Dr John Stockton wrote:
>Timo Salmi <ts@uwasa.fi> posted :
>>J Smith wrote:
>>>How do I grep for a line with a tab?
>>>grep "\t" file.txt
>>>does not work

>>Depends on the grep you use. The grep from this one will work as
>>desired in the above

> MiniTrue will do it, expressing the tab either as an actual tab or (in
> the default -x+ state) as \x09.
> At ftp://garbo.uwasa.fi/pc/fileutil/mtr206b.zip

True, if you pardon the feeble pun. Likewise, the more common G(nu)awk
tool could be used. Within a batch file one could have e.g.
  gawk "/\t/{printf \"%%s\n\", $0}" MYFILE.TXT
or, in fact even
  gawk "/\x09/{printf \"%%s\n\", $0}" MYFILE.TXT

Likewise, sed could be used
  sed -n "/\t/p" C:\_M\TEST.TXT

However, there may be complications dependind on the gawk and sed
versions. Not all of them recognize Windows long file names (LFNs).
Thus short file name (SFN) conversion might be first be needed. For
example
  @echo off & setlocal enableextensions
  set file_=C:\_D\TEST\My test file.txt
  for /f "tokens=*" %%f in ("%file_%") do set file_=%%~sf
  gawk "/\t/{printf \"%%s\n\", $0}" "%file_%"
  endlocal & goto :EOF
Note that the SFN extraction is not immune against the poison
characters.

The extra programs can be avoided by using a pure command line script
FINDSTR solution:
  @echo off & setlocal enableextensions
  findstr /c:"TheLiteralTabCharacter" "C:\_D\TEST\My test file.txt"
  endlocal & goto :EOF
How you enter the literal tab character depends on the text editor you
use.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:07 2011
Subject: 127) How can I pad leading zeros or like to a variable?
Date: Mon, 31 Jan 2011 01:02:07
From: ts@uwasa.fi (Timo Salmi)

The solution already is embedded within a couple of items in this FAQ collection, but let's revisit the question and make it a separate item. The code below adds leading zeros to the replaceable parameter %1 making it exactly five characters long.
  @echo off & setlocal enableextensions
  set var_=00000%1
  set var_=%var_:~-5%
  echo %var_%
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq 23
  00023
or
  C:\_D\TEST>cmdfaq 12345678
  45678

Written much more generally with a subroutine we can have
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~0 MyTestString
    goto :EOF)
  call :LeadVar "%~1" 0 5 padded_
  echo.%padded_%
  endlocal & goto :EOF
  ::
  :: ===============================================================
  :: Subroutine: A generic padding of a string
  :LeadVar MyString PadWith MaxLength return_
  setlocal enableextensions enabledelayedexpansion
    set PadWith=%~2
    set MaxLength=%~3
    for /L %%a in (1,1,%MaxLength%) do set MyString=!MyString!!PadWith!
    set MyString=%MyString%%~1
    set return_=!MyString:~-%MaxLength%!
  endlocal & set "%~4=%return_%" & goto :EOF
An example of the output:
  C:\_D\TEST>cmdfaq "12 4"
  012 4

Another take. See the usage FuncRightJustify function which is part
of the WHEREIS.CMD script included in this collection. (It uses
spaces instead of zeros.) Useful for justifying columns.
  :FuncRightJustify arg1 arg2
  setlocal enableextensions
  set number_=            %1
  set number_=%number_:~-12%
  endlocal & set "%2=%number_%" & goto :EOF

Just for the sake of interest, let's write also a G(nu)AWK solution
to the problem.
  @echo off & setlocal enableextensions
  set var_=00000%1
  echo %var_%|gawk '{printf "@set var_=%%05d\n",$0}'>"%TEMP%\tmp$$$.cmd"
  for %%c in (call del) do %%c "%TEMP%\tmp$$$.cmd"
  echo %var_%
  endlocal & goto :EOF

The gawk snippet could be formulated in other ways as well. For
example the more complicated
  gawk '{i="00000"$1}{p=length(i)}{printf "@set var_=%%s\n",substr(i,p-4,p)}

The task can for further demonstration be also solved with a VBScipt-
aided formulation:
  @echo off & setlocal enableextensions
  ::
  set var_=%~1
  ::
  :: Build a Visual Basic Script
  set skip=
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set vbs_=%temp_%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  for /f "tokens=*" %%a in ('
    cscript //nologo "%vbs_%" "%var_%"') do (
      set paddedvar_=%%a)
  ::
  :: Display the result
  echo %paddedvar_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Set arg = WScript.Arguments 'VBS
  Wscript.Echo PadFn(arg(0),5) 'VBS
  '
  Function PadFn (str, n) 'VBS
    PadFn = Right(String(n-1,"0")&str,n) 'VBS
  End Function 'VBS
The output could be e.g.
  C:\_D\TEST>cmdfaq 23
  00023
or
  C:\_D\TEST>cmdfaq 12345678
  45678

Alternatively, we might wish to have
  Function PadFn (str, n) 'VBS
    If Len(str) > n Then 'VBS
      PadFn = str 'VBS
    Else 'VBS
      PadFn = Right(String(n-1,"0")&str,n) 'VBS
    End If 'VBS
  End Function 'VBS
The output could be e.g.
  C:\_D\TEST>cmdfaq 23
  00023
or
  C:\_D\TEST>cmdfaq 12345678
  12345678

A brief way of writing the VBS-aided solution
  @echo off & setlocal enableextensions
  set var_=%~1
  echo %var_%
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Right(String(5-1,"0")^&"%var_%",5)
  for /f "tokens=* delims=" %%a in (
    'cscript //nologo "%temp%\tmp$$$.vbs"') do set var_=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  echo %var_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq 23
  23
  00023
or
  C:\_D\TEST>cmdfaq 12345678
  12345678
  45678
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:08 2011
Subject: 128) How to prevent SET /P input from entering the command history?
Date: Mon, 31 Jan 2011 01:02:08
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  set cmdfile=C:\_M\TEMP\temp$$$.cmd
  >  %cmdfile% echo @echo off
  >> %cmdfile% echo set /p var_="Give your input? "
  >> %cmdfile% echo echo %%var_%%
  for %%c in ("cmd /c" del) do %%c %cmdfile%
  endlocal & goto :EOF
Output
  C:\_D\TEST>cmdfaq
  Give your input? Hello World
  Hello World
The "Hello World" is not in the command history.

Or use a call like
  CMD /C myscript.cmd

Incidentally, the first option could also be formulated as
  @echo off & setlocal enableextensions
  set cmdfile=C:\_M\TEMP\temp$$$.cmd
  (
    echo @echo off
    echo set /p var_="Give your input? "
    echo echo %%var_%%
  )> "%cmdfile%"
  for %%c in ("cmd /c" del) do %%c "%cmdfile%"
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=43bfd8f0%240%242719%24ed2619ec%40ptn-nntp-reader02.plus.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:09 2011
Subject: 129) Is it possible to stop and reset the print spooler with a script?
Date: Mon, 31 Jan 2011 01:02:09
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  echo Ŀ
  echo  CLRSPOOL.CMD Stop and reset print spooler          
  echo  By Prof. Timo Salmi, Last modified Sun 29-Jan-2006 
  echo 
  ::
  if "%~1"=="?" goto _usage
  if "%~1"=="/?" goto _usage
  ::
  :: The path to the spooler files
  set spool_=C:\WINDOWS\system32\spool\PRINTERS
  ::
  :: Spool contents
  dir "%spool_%"
  echo.
  ::
  :: Ask for confirmation
  :_ask
  set ask_=
  set /p ask_="Reset the print spooler [Y/n]?"
  if /i "%ask_%"=="n" goto _out
  if /i not "%ask_%"=="y" if not "%ask_%"=="" goto _ask
  ::
  :: Clear the spooler
  net stop spooler
  for %%f in ("%spool_%\*.*") do (
    if exist "%%f" del "%%f"
    )
  net start spooler
  dir "%spool_%"
  :: See FAQ item #2 for an explanation of the next line
  if not defined cmdbox if defined PauseIfFromDesktop pause
  goto _out
  ::
  :_usage
  echo.
  echo Usage: DELSPOOL
  echo.
  echo High enough user privileges are required to complete this task.
  echo Else the net stop/start commands will just produce error messages.
  goto _out
  ::
  :_out
  endlocal & goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:10 2011
Subject: 130) How do I find and delete files which contain a specific text?
Date: Mon, 31 Jan 2011 01:02:10
From: ts@uwasa.fi (Timo Salmi)

> I have a folder which contains about 250000 files.
> File explorer chokes or is slow when I try to search for files
> which contain a certain a certain phrase.
> I would like to delete these files without using a gui program.
> What's the dos syntax to do this in a command prompt?

As by the script solution below. Incidentally, note explicitly not
using the errorlevel, but && instead.
  @echo off & setlocal enableextensions
  for %%f in ("C:\wherever\*.*") do (
    find /i "whatever" "%%f">nul&&ECHO del "%%f")
  endlocal & goto :EOF

WARNING!
========
The "ECHO" is included for some safety. Careful, as always! Use
scripts with del or other powerful commands at your own risk! A del
from command line or from a script is irreversible.

References/Comments:
  hh ntcmds.chm::/ntcmds_shelloverview.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:11 2011
Subject: 131) How to get the language of Windows XP in a script?
Date: Mon, 31 Jan 2011 01:02:11
From: ts@uwasa.fi (Timo Salmi)

Matthias Tacke wrote:
> the information provided by foxidrives link includes in one
> posting: reg query "HKEY_CURRENT_USER\Control Panel\International"

That's nicely advanced, while easy to act on.

> It's no big deal to extract portions in a batch.

E.g.
  @echo off & setlocal enableextensions
  for /f "tokens=3" %%i in (
    'reg query "HKEY_CURRENT_USER\Control Panel\International" ^| find "sLanguage"') do (
    set lang_=%%i)
  echo %lang_%
  endlocal & goto :EOF

Which would give for example
  C:\_D\TEST>cmdfaq
  ENU

> http://www.microsoft.com/globaldev/reference/winxp/langtla.mspx

Which, in turns shows
  English - United States ENU 0409

A much less accurate method would be to see what is produced by
  ver /?|find "Windows XP"

Yet another method:
  @echo off & setlocal enableextensions
  for /f "tokens=2 delims=:;" %%i in (
    'systeminfo^|find "System Locale:"') do (
    set lang_=%%i)
  echo %lang_: =%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  en-us

References/Comments:
 http://www.google.com/groups?selm=oj7as1dve5v5%24.es2rzjwjvd1e.dlg%4040tude.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:12 2011
Subject: 132) How to find out the next weekday given today's?
Date: Mon, 31 Jan 2011 01:02:12
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  set  Day=%~1
  set  week=Sun Mon Tue Wed Thu Fri Sat Sun
  call set SubWeek=%%Week:*%day%=%%
  Set  NextDay=%SubWeek:~1,3%
  echo After %Day% comes %NextDay%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq thu
  After thu comes Fri

A similar task for the next character, with the Finnish alphabet
  @echo off & setlocal enableextensions
  set letter=%1
  set alpha=abcdefghijklmnopqrstuvwxyza
  call set beta=%%alpha:*%letter%=%%
  set last=%beta:~,1%
  echo After %letter% comes %last%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq 
  After  comes 

References/Comments:
 The inventive method is due to Clay Calvert:
 http://www.google.com/groups?selm=e1j2v1hhog4ncpgc38uebm9jlv4ktn8kp0%404ax.com
Also of interest:
 http://www.jsifaq.com/SF/Tips/Tip.aspx?id=9830
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:13 2011
Subject: 133) How do I get the current IP address, number and name?
Date: Mon, 31 Jan 2011 01:02:13
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  :: Test first
  ipconfig|find "IP Address">nul
  if %errorlevel% GTR 0 (
    echo Not connected
    goto :EOF)
  ::
  :: Get the current IP
  for /f "tokens=2 delims=:" %%i in (
    'ipconfig /all^|find "IP Address"'
    ) do set ip=%%i
  set ip=%ip: =%
  echo %ip%
  ::
  :: Look up the IP address on the name server
  for /f "tokens=2 delims=:" %%n in (
    'nslookup %ip%^|find "Name:"'
    ) do set name=%%n
  set name=%name: =%
  echo %name%
  endlocal & goto :EOF

The output might be e.g.
  D:\TEST>cmdfaq
  193.166.122.2
  reimari.uwasa.fi
or
  D:\TEST>cmdfaq
  Not connected
--------------------------------------------------------------------
From ts@uwasa.fi Mon Jan 31 01:02:14 2011
Subject: 134) How do I advance the dates of my certain JPG files by one year?
Date: Mon, 31 Jan 2011 01:02:14
From: ts@uwasa.fi (Timo Salmi)

You'll need a touch utility port for the script below.

  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  rem Note, assumes date format DD.MM.YYYY hh:mm
  rem E.g. 21.02.2006 08:14
  ::
  :: Usage
  if "%~1"=="" (
    echo Usage: %~0 [Filename]
    goto :EOF
    )
  :: Check that the file(s) to be restamped exist
  if not exist "%~1" (
    echo File^(s^) "%~1" not found
    goto :EOF
    )
  ::
  :: Store the potential time zone information, and make a note
  if defined tz (
    echo @rem the current timezone TZ is %TZ%
    echo set TZ=
    )
  set storetz=%tz%
  set tz=
  ::
  :: Get the old stamps and display the commands for changing them
  for %%f in ("%~1") do (
    set filename=%%~dpnxf
    set filestamp=%%~tf
    set filedd=!filestamp:~0,2!
    set filemm=!filestamp:~3,2!
    set fileyear=!filestamp:~6,4!
    set filehour=!filestamp:~11,2!
    set filemin=!filestamp:~14,2!
    ::
    set /a fileyear_new=!fileyear! + 1
    echo touch -c -f !filemm!!filedd!!filehour!!filemin!!fileyear_new! !filename!
    )
  ::
  :: Restore the original timezone information
  set tz=%storetz%
  if defined tz echo set TZ=%tz%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq C:\_H\PHOTO\HME2006A\*.JPG
  @rem the current timezone TZ is Europe/Helsinki
  set TZ=
  touch -c -f 011513242007 C:\_H\PHOTO\HME2006A\66011507.JPG
  touch -c -f 020213322007 C:\_H\PHOTO\HME2006A\66020201.JPG
  set TZ=Europe/Helsinki

Remove the safety echos when you want to do it for real.

The above example was for exactly a one year increment. For generic
changes for any number of days from now on, or back, take the needed
additional cues from item #31.

The is a slight catch. The method zeroes the seconds part, since XP
will not display them. E.g. a VBS-aided script, such as my included
"FILEINFO.VBS FileInfo Visual Basic Script" would be needed to get
also the seconds in a file's datestamp.

If you wish to be very orthodox, check that the touch you use knows
how to handle the very rare case of Feb 29 correctly.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:15 2011
Subject: 135) How do I get information about a file extension association?
Date: Mon, 31 Jan 2011 01:02:15
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (
    echo Usage: %~0 .extension
    goto :EOF
    )
  set ext_=%~1
  ::
  echo %ext_%|find "=" > nul
  if %errorlevel% EQU 0 (
    echo Equal signs not allowed for safety reasons in %ext_%
    goto :EOF
    )
  ::
  for /f "tokens=2 delims==" %%a in (
    'assoc^|find /i "%ext_%"') do set assoc_=%%a
  echo %ext_% %assoc_%
  ::
  if defined assoc_ (
    reg query HKLM\SOFTWARE\Classes\%assoc_%|find "REG_SZ"
    echo.
    reg query HKLM\SOFTWARE\Classes\%assoc_%\shell|find "shell\"
    echo.
    for /f "tokens=1* delims==" %%a in ('assoc %ext_%') do ftype %%b
    ) else (
    echo No association)
  ::
  ::
  endlocal & goto :EOF

The output might be e.g.

  C:\_D\TEST>cmdfaq .html
  .html FirefoxHTML
      AlwaysShowExt       REG_SZ
      <NO NAME>   REG_SZ  HTML Document
  HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FirefoxHTML\shell\Edit_with_Notepad
  HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FirefoxHTML\shell\open
  HKEY_LOCAL_MACHINE\SOFTWARE\Classes\FirefoxHTML\shell\Open_with_Mozilla
  FirefoxHTML=C:\PROGRA~1\MOZILL~1\FIREFOX.EXE -url "%1"

  C:\_D\TEST>cmdfaq .dir
  .dir
  No association

References/Comments:
 http://www.google.com/groups?selm=avpk021kgkf4bnn5ad3eiotk9i5d261luj%404ax.com
 http://www.google.com/groups?selm=pan.2006.03.05.20.03.41.859000%40virgin.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:16 2011
Subject: 136) How do I find out when my PC was last booted?
Date: Mon, 31 Jan 2011 01:02:16
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  for /f "tokens=3,4" %%d in (
    'net statistics workstation^|find "Statistics since"') do (
    set lastboot=%%d %%e
    )
  echo Last booted %lastboot%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  Last booted 11.04.2006 09:17

Alternatively, suggested by Phil Robyn
  @echo off & setlocal enableextensions
  for /f "tokens=1,2" %%d in (
    'dir /ah /s C:\pagefile.sys^|find /i "pagefile.sys"') do (
    set lastboot=%%d %%e
    )
  echo Last booted %lastboot%
  endlocal & goto :EOF

There is yet another way. As it happens, I have the following script
in the Startup folder, which is directly pertinent to the question
discussed:
  @echo off & setlocal enableextensions
  set target_=C:\_L\TIMO\logon.txt
  ::
  color 0B
  echo +-------------------------------+
  echo : Logging the user's logon      :
  echo : A script by Prof. Timo Salmi  :
  echo : Last modified Thu 15-Feb-2007 :
  echo +-------------------------------+
  echo.
  echo %date% %time%
  echo Making an entry to %target_%
  ::
  if not defined temp goto :EOF
  set temp_=%temp%
  if exist c:\_l\temp set temp_=C:\_L\TEMP
  for /f "tokens=*" %%f in ("%temp_%") do set temp_=%%~sf
  ::
  gawk 'BEGIN{printf"@set wd_=%%s\n",strftime("%%a",systime())}'>%temp_%\weekday$.cmd
  for %%c in (call del) do %%c %temp_%\weekday$.cmd
  ::
  echo Logon: %COMPUTERNAME% %wd_% %date% %time% %USERNAME%>%temp_%\logon1.tmp
  if not exist %target_% (
    copy /y %temp_%\logon1.tmp %target_% > nul
    goto _out
    )
  copy %target_% %temp_%\logon2.tmp > nul
  copy /y %temp_%\logon1.tmp + %temp_%\logon2.tmp %target_% > nul
  ::
  :_out
  for %%f in (logon1.tmp logon2.tmp weekday$.cmd) do if exist %temp_%\%%f del %temp_%\%%f
  endlocal & goto :EOF

Alternatively:
  @echo off & setlocal enableextensions
  for /f "tokens=* skip=1" %%i in ('wmic OS Get LastBootUpTime') do (
    set LastBootUpTime=%%i)
  echo LastBootUpTime: %LastBootUpTime%
  endlocal & goto :EOF

To get the System Up Time:
  @echo off & setlocal enableextensions
  for /f "tokens=2 delims=:" %%a in ('
    systeminfo^|find "System Up Time:"') do (
      set uptime_=%%a)
  for /f "tokens=* delims= " %%a in ('
    echo %uptime_%') do set uptime_=%%a
  echo uptime_=%uptime_%
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  uptime_=2 Days 10 Hours 28 Minutes 46 Seconds

References/Comments:
 http://www.google.com/groups?selm=MWk0g.27299%24WI1.12525%40pd7tw2no
 http://support.microsoft.com/kb/555737
 http://support.microsoft.com/kb/232243
 http://support.microsoft.com/kb/290216/en-us
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:17 2011
Subject: 137) I need to resize a group of images from the command line.
Date: Mon, 31 Jan 2011 01:02:17
From: ts@uwasa.fi (Timo Salmi)

To do this you need a good image processing program like Irfan
Skiljan's IrfanView.

  @echo off & setlocal enableextensions
  ::
  echo +----------------------------------------------------------+
  echo : IR_SCALED.CMD Resize a set of .jpg images to 80x60 pixels :
  echo : By Prof. Timo Salmi, Last modified Mon 11-Aug-2008       :
  echo +----------------------------------------------------------+
  echo.
  ::
  :: Set the defaults
  set ir="C:\Program Files\IrfanView\i_view32.exe"
  set sourceDir=C:\_M
  set targetDir=C:\_M\SCALED
  set pixW=80
  set pixH=60
  ::
  :: Is help needed
  if "%~1"=="?" goto _help
  if "%~1"=="/?" goto _help
  if /i "%~1"=="/help" goto _help
  ::
  :: If necessary, create the target folder
  if not exist %targetDir% mkdir %targetDir%
  ::
  :: Convert with IrfanView command line
  :: See IrfanView Help "Command Line Options" for the switches
  for %%f in (%sourceDir%\*.JPG) do (
    start "" /wait %ir% %%~ff /resize_long=%PixW% /aspectratio /resample /jpgq=75 /convert=%targetDir%\%%~nf_scaled%%~xf
    )
  ::
  :: Show the results
  dir %targetDir%
  goto _out
  ::
  :_help
  echo Usage: IR_SCALE
  echo.
  echo Default source folder: %sourceDir%
  echo Default target folder: %targetDir%
  ::
  :_out
  endlocal & goto :EOF

Another option is the NConvert command line program. The advantage of
NConvert is that it does not require a Windows installation. It is a
ready to run utility in the CLI. The disadvantage is that unlike in
IrfanView /resize_long we need to know in advance whether the image is
vertical or horizontal.
  @echo off & setlocal enableextensions
  set nconvert=C:\_F\BOX\BOXTOOLS\nconvert.exe
  set filelist=C:\_M\TEMP\filelist.txt
  if not exist C:\_M\SCALED\ mkdir C:\_M\SCALED
  ::
  > "%filelist%" echo C:\_M\68080701.JPG
  >>"%filelist%" echo C:\_M\68080702.JPG
  >>"%filelist%" echo C:\_M\68080703.JPG
  ::
  "%nconvert%" -keepfiledate -ratio -resize 60 0 -o C:\_M\SCALED\68073003_scaled.JPG C:\_M\68073003.JPG
  "%nconvert%" -keepfiledate -ratio -resize 80 0 -o C:\_M\SCALED\%%_scaled.JPG -l "%filelist%"
  ::
  for %%f in ("%filelist%") do if exist %%f del %%f
  endlocal & goto :EOF

IrfanView can be used to get an image's dimensions into environment variables:
  @echo off & setlocal enableextensions
  set ir=C:\Program Files\IrfanView\i_view32.exe
  set tmpfile_=C:\_M\irfan.tmp
  set image_=C:\_M\68073003.JPG
  ::
  "%ir%" "%image_%" /info="%tmpfile_%"
  for /f "tokens=4,6" %%a in ('
    type "%tmpfile_%"^|find "Image dimensions"') do (
      set width_=%%a
      set height_=%%b)
  for %%f in ("%tmpfile_%") do if exist %%f del %%f
  echo "%image_%"
  echo width_=%width_% height_=%height_%
  endlocal & goto :EOF

The output would be e.g.
  C:\_M>c:\_d\test\cmdfaq
  "C:\_M\68073003.JPG"
  width_=768 height_=1024

Also NCovert can be used to get an image's dimensions:
  @echo off & setlocal enableextensions
  set nconvert=C:\_F\BOX\BOXTOOLS\nconvert.exe
  set tmpfile_=C:\_M\nconvert.tmp
  set image_=C:\_M\68073003.JPG
  ::
  "%nconvert%" -info "%image_%"|find "Width ">"%tmpfile_%"
  for /f "tokens=2 delims=:" %%a in ('
    type "%tmpfile_%"') do set width_=%%a
  "%nconvert%" -info "%image_%"|find "Height ">"%tmpfile_%"
  for /f "tokens=2 delims=:" %%a in ('
    type "%tmpfile_%"') do set height_=%%a
  for %%f in ("%tmpfile_%") do if exist %%f del %%f
  set width_=%width_: =%
  set height_=%height_: =%
  echo "%image_%"
  echo width_=%width_% height_=%height_%
  endlocal & goto :EOF
The output would be e.g.
  C:\_M>c:\_d\test\cmdfaq
  "C:\_M\68073003.JPG"
  width_=768 height_=1024

References/Comments:
 http://www.irfanview.com/
 http://pagesperso-orange.fr/pierre.g/xnview/en_nconvert.html
 http://www.imagemagick.org/script/index.php
 http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx
 http://www.google.com/groups?selm=1dd29q20m7kc9%24.1t7olhjmxvmbs.dlg%4040tude.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:18 2011
Subject: 138) How can I get the long name of a short-named file or folder?
Date: Mon, 31 Jan 2011 01:02:18
From: ts@uwasa.fi (Timo Salmi)

Getting the short name of a file or folder is relatively easy with
FOR /F and %%~sI but the reverse is more complicated.

> Is it possible to cd to short-named dir, but prompt to show full,
> long name?

The question essentially is, when in a short-named folder, how can
one get its long name? The solution below should do this, for XP at
least

  @echo off & setlocal enableextensions
  cd C:\DOCUME~1
  for /f %%d in ("%cd%") do set name_=%%~nd
  for /f %%p in ("%cd%") do set path_=%%~dpp
  for /f "tokens=* delims=" %%a in (
    'dir /x ..^|find "%name_%"') do set long_=%%a
  set long_=%long_:~49%
  echo %path_%%long_%
  endlocal & goto :EOF

The output would be
  C:\_M>c:\_d\bas\cmdfaq
  C:\Documents and Settings

More generally:
  @echo off & setlocal enableextensions
  echo.
  echo +----------------------------------------------------+
  echo : Get the long name of a short-named folder or file  :
  echo : By Prof. Timo Salmi. Last modified Fri 28-Apr-2006 :
  echo +----------------------------------------------------+
  echo.
  ::
  :: Usage
  if "%~1"=="" (
    echo Usage: %~f0 "ShortFolderOrFileName"
    goto :EOF
    )
  ::
  :: Check that it is about a short name
  echo "%~1"|find "~">nul
  if %errorlevel% GTR 0 (
    echo "%~1" is not a valid short name
    goto :EOF
    )
  ::
  :: Check the existence
  if not exist "%~1" (
    echo "%~1" not found
    goto :EOF
    )
  ::
  :: Get and process the information
  for /f %%d in ("%~1") do set name_=%%~nd
  for /f %%p in ("%~1") do set path_=%%~dpp
  for /f "tokens=* delims=" %%a in (
    'dir /x "%1\.."^|find "%name_%"') do set long_=%%a
  set long_=%long_:~49%
  ::
  :: Show the results
  echo %~1
  echo %path_%%long_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_M>c:\_d\bas\cmdfaq "C:\_D\BAS\KOE2~1.CMD"
  C:\_D\BAS\KOE2~1.CMD
  C:\_D\BAS\KOE 2.CMD

There is an even simple solution to the problem of displaying the
long-name format of the current folder as captured below

  C:\DOCUME~1>attrib %cd%
             C:\Documents and Settings

Developed from that we get:
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    set dir_=%cd%
    ) else (
    set dir_=%~1
    )
  ::
  echo %dir_%|findstr /e "\\" > nul
  if %errorlevel% EQU 0 (
   echo Drop the trailing backslash \
   goto :EOF)
  ::
  if not exist "%dir_%\" (
   echo "%dir_%" no such folder
   goto :EOF)
  ::
  for /f "tokens=* delims=" %%d in (
    'attrib "%dir_%"') do set long_=%%d
  set long_=%long_:~11%
  ::
  echo %dir_%
  echo %long_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_M>C:\_D\BAS\CMDFAQ C:\DOCUME~1
  C:\DOCUME~1
  C:\Documents and Settings

The problem with the above solutions is that they work one level at
the time only. Thus one has to walk through, which takes some doing.
A fullpath solution to the problem is given below
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Display intermediate information for debugging or not
  set debug=true
  set debug=
  ::
  :: Usage
  if "%~1"=="" (
    echo.
    echo Usage: %~0 [FolderOrFileName]
    goto :EOF
    )
  ::
  :: Give the name of the folder or the file
  set name=%~f1
  if not exist "%name%" (
    echo "%name%" not found
    goto :EOF)
  ::
  :: Parse the path elements
  set count_=0
  set rest_=%name%
  :_loop
  for /f "tokens=1* delims=\" %%a in ("%rest_%") do (
    set /a count_+=1
    set part[!count_!]=%%a
    set rest_=%%b
    if defined rest_ goto _loop
    )
  ::
  :: Display the individual parts
  if defined debug (
    for /l %%i in (1,1,%count_%) do (
      echo part[%%i]=!part[%%i]!
      )
    echo.
    )
  ::
  :: Build up the path
  for /l %%i in (1,1,%count_%) do (
    set longpath_=!longpath_!!part[%%i]!\
    if %%i GTR 1 (
      for /f "tokens=* delims=" %%f in (
        'attrib "!longpath_:~0,-1!"') do (
        set longpath_=%%f
        set longpath_=!longpath_:~11!\
        )
      if defined debug echo !longpath_!
      )
    )
  set longpath_=%longpath_:~0,-1%
  ::
  :: Display the result
  echo The given format was:
  echo %name%
  echo The long format is:
  echo %longpath_%
  ::
  endlocal & goto :EOF

Examples of the output
  C:\_D\TEST>cmdfaq %temp%
  The given format was:
  C:\DOCUME~1\ts\LOCALS~1\Temp
  The long format is:
  C:\Documents and Settings\ts\Local Settings\Temp

  C:\_D\TEST>cmdfaq %temp%\jupdate1.5.0.xml
  The given format was:
  C:\DOCUME~1\ts\LOCALS~1\Temp\jupdate1.5.0.xml
  The long format is:
  C:\Documents and Settings\ts\Local Settings\Temp\jupdate1.5.0.xml

  C:\_D\TEST>cmdfaq C:\DOCUME~1\ts\LOCALS~1
  The given format was:
  C:\DOCUME~1\ts\LOCALS~1
  The long format is:
  C:\Documents and Settings\ts\Local Settings

  C:\_D\TEST>cmdfaq TEST3~1.CMD
  The given format was:
  C:\_D\BAS\TEST3~1.CMD
  The long format is:
  C:\_D\BAS\TEST  3.CMD

References/Comments:
 http://www.google.com/groups?selm=D7q4g.3%24zR3.2%40newssvr33.news.prodigy.com
 http://www.google.com/groups?selm=fq8is2pq03ckcsb4so0d6075bsc2qkud8o%404ax.com
--------------------------------------------------------------------
From ts@uwasa.fi Mon Jan 31 01:02:19 2011
Subject: 139) How do I convert UNIX newlines to PC eolns? And vice versa?
Date: Mon, 31 Jan 2011 01:02:19
From: ts@uwasa.fi (Timo Salmi)

The PC eoln (end of line) is an ASCII 13 10 pair.
The UNIX eoln is ASCII 10.

Using SED:
  @echo off & setlocal enableextensions
  rem UNIX newlines to PC eolns
  set source_=C:\_M\UNIX.TXT
  set target_=C:\_M\PC.TXT
  sed -e "s/\x0a/\x0d\x0a/" %source_% > %target_%
  endlocal & goto :EOF

Written in a more "filename, handle and program version tolerant" way
  @echo off & setlocal enableextensions
  rem UNIX newlines to PC eolns
  set source_=C:\_M\My UNIX test.TXT
  set target_=C:\_M\My PC test.TXT
  < "%source_%" sed -e "s/\x0d\x0a/\x0a/" > "%target_%"
  endlocal & goto :EOF

In fact, any "dummy" sed conversion will do:
  sed -e "s/ / /" < "%source_%" > "%target_%"

Using G(nu)AWK
  @echo off & setlocal enableextensions
  rem UNIX newlines to PC eolns
  set source_=C:\_M\UNIX.TXT
  set target_=C:\_M\PC.TXT
  gawk "BEGIN{RS=\"[\012]\"}{print $0}" "%source_%" > "%target_%"
  endlocal & goto :EOF

Actually, to convert a text file with UNIX newlines to PC eolns no
third party utilities are necessary:
  @echo off & setlocal enableextensions
  rem UNIX newlines to PC eolns
  set source_=C:\_M\My UNIX test.TXT
  set target_=C:\_M\My PC test.TXT
  more < "%source_%" > "%target_%"
  endlocal & goto :EOF
or
  @echo off & setlocal enableextensions
  rem UNIX newlines to PC eolns
  set source_=C:\_M\My UNIX test.TXT
  set target_=C:\_M\My PC test.TXT
  find /v "" < "%source_%" > "%target_%"
  endlocal & goto :EOF

The reverse task, PC --> UNIX eolns can be done e.g. as follows
  @echo off & setlocal enableextensions
  rem PC eolns to UNIX newlines
  set source_=C:\_M\My PC test.TXT
  set target_=C:\_M\My UNIX test.TXT
  unxtr -d \015 < "%source_%" > "%target_%"
  endlocal & goto :EOF
Where \015 is octal for ASCII 13 (decimal).

There naturally also is a number of specialized third-party
utilities to do the conversions, including
 ftp://garbo.uwasa.fi/pc/ts/tsfilt25.zip
 Programs for filtering messages, log files, Unix-PC, etc

The reverse task, i.e. converting PC eolns to UNIX newlines is most
naturally done on the UNIX host e.g. with the following Bourne Shell
script:
 ftp://garbo.uwasa.fi/unix/ts/pc2unix
 Filter PC end of lines to Unix end of lines, T.Salmi

You may also wish to see the items #15 and #163.

References/Comments:
 http://www.google.com/groups?selm=lgm252lltdge4rqn37i7rvm7ee60op7u8i%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:20 2011
Subject: 140) How do I count how many times a word appears in my text file?
Date: Mon, 31 Jan 2011 01:02:20
From: ts@uwasa.fi (Timo Salmi)

This is how to do it. First decompose the original text file so that
each word is on a line of its own. Then get with find the number of
lines with the word appearing.
  @echo off & setlocal enableextensions
  set source_=C:\wherever\MYFILE.TXT
  <A HREF="tscmd.php#sed">sed</A> -e "s/[\x20\x09]/\x0d\x0a/g" %source_% > "%temp%\words.tmp"
  for /f "tokens=3" %%c in ('
    find /i /c "mytext" "%temp%\words.tmp"') do set count_=%%c
  echo Found your word %count_% times
  for %%f in ("%temp%\words.tmp") do if exist %%f del %%f
  endlocal & goto :EOF
Hexadecimal [\x20\x09] denotes the appearance of either a space or a tab.
Hexadecimal \x0d\x0a inserts an eoln (end of line).

Consider finding how many times the word "the" appears in the
explanation test before the code above. Substituting "the" in place
of "mytext" we get
  C:\_D\TEST>cmdfaq
  Found your word 4 times

Why 4 times, not 3? Because also the word "Then" is matched. If we
wish to get the strict answer, the we have to adjust the code as
follows
  @echo off & setlocal enableextensions
  set source_=C:\wherever\MYFILE.TXT
  < "%source_%" sed -e "s/[\x20\x09]/\x0d\x0a/g" > "%temp%\words.tmp"
  for /f "tokens=*" %%c in ('
    findstr /i /x /c:"the" "%temp%\words.tmp"') do (
    if %errorlevel% EQU 0 set /a count_+=1)
  echo Found your word %count_% times
  for %%f in ("%temp%\words.tmp") do if exist %%f del %%f
  endlocal & goto :EOF

Or with G(nu)AWK:
  @echo off & setlocal enableextensions
  set source_=C:\wherever\MYFILE.TXT
  gawk "{j=1;while(j<=NF){if($j==\"myword\"){n++};j++};j=1};END{print \"@set count_=\"n}" "%source_%">"%temp%\setcount.cmd"
  for %%c in (call del) do %%c "%temp%\setcount.cmd"
  echo Found your word %count_% times
  endlocal & goto :EOF
The gawk solution is more accurate in the sense that it does not
count partial word occurrences. It also is case sensitive.

The problem can also be solved with a Visual Basic Script (VBScript)
aided command-line script. Furthermore, assume (to make the solution
more generic) that besides spaces, tabs, periods, and commas can
separate words.
  @echo off & setlocal enableextensions
  ::
  :: The data file to be inspected
  set source_=C:\_M\My test file.txt
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  < "%source_%" cscript //nologo "%vbs_%" > "%temp%\words.tmp"
  ::
  :: Do the counting
  for /f "tokens=*" %%c in ('
    findstr /i /x /c:"MyWord" "%temp%\words.tmp"') do (
    if %errorlevel% EQU 0 set /a count_+=1)
  ::
  :: Display the result
  echo Found your word %count_% times
  ::
  :: Clean up
  for %%f in ("%vbs_%" "%temp%\words.tmp") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '............................................
  ' The Visual Basic Script
  '
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    LineStr = WScript.StdIn.ReadLine 'VBS
    LineStr = Replace(LineStr, Chr(9), " ") 'VBS
    LineStr = Replace(LineStr, ".", " ") 'VBS
    LineStr = Replace(LineStr, ",", " ") 'VBS
    LineArray = Split(LineStr, " ", -1, vbTextCompare) 'VBS
    For i = 0 to UBound(LineArray) 'VBS
      WScript.StdOut.WriteLine LineArray(i) 'VBS
    Next 'VBS
  Loop 'VBS
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:21 2011
Subject: 141) Why isn't the ! character always echoed as expected?
Date: Mon, 31 Jan 2011 01:02:21
From: ts@uwasa.fi (Timo Salmi)

This is a result of a side effect. The exclamation mark is used to
expand environment variables at execution time if the delayed
variable expansion is enabled in a script. This affects how the !
character is treated. Note the different outputs in the following
demonstration:

  @echo off
  setlocal enableextensions enabledelayedexpansion
  echo delayed expansion enabled
  echo.WOW!!!
  echo.WOW^!^!^!
  echo.WOW^^!^^!^^!
  echo.! test! addition suggested by foxidrive!
  echo.!test! addition suggested by foxidrive!
  setlocal enableextensions disabledelayedexpansion
  echo.
  echo delayed expansion disabled
  echo.WOW!!!
  echo.WOW^!^!^!
  echo.WOW^^!^^!^^!
  echo.! test! addition suggested by foxidrive!
  echo.!test! addition suggested by foxidrive!
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  delayed expansion enabled
  WOW
  WOW
  WOW!!!
   test
   addition suggested by foxidrive

  delayed expansion disabled
  WOW!!!
  WOW!!!
  WOW^!^!^!
  ! test! addition suggested by foxidrive!
  !test! addition suggested by foxidrive!

Browse throughout the items in this FAQ for several examples of
using the delayed expansion for its actual purpose. For example,
consider the task of listing today's files in the current folder.
One of the possible ways of formulating that is
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%f in ("*.*") do (
    echo "%%~tf" | find "%date%" > nul
    if !errorlevel! EQU 0 echo %%~tf %%~zf "%%~ff"
    )
  endlocal & goto :EOF
The output might be
  C:\_D\TEST>cmdfaq
  20.05.2006 10:10 21928 "C:\_D\TEST\BATFAQ2.BAT"
  20.05.2006 10:22 216 "C:\_D\TEST\CMDFAQ.CMD"

Note !errorlevel! not %errorlevel%.
Incidentally, in this particular case also the following formulation
would work
  if not errorlevel 1 echo %%~tf %%~zf "%%~ff"
but even if important formulation lore that is beside the current
point on delayed expansion.

Aligning the output demontrates further
  @echo off & setlocal enableextensions enabledelayedexpansion
  for %%f in ("*.*") do (
    echo "%%~tf" | find "%date%" > nul
    if not errorlevel 1 (
      set fdate=%%~tf
      set fsize=%%~zf
      set fsize=          !fsize!
      set fsize=!fsize:~-10!
      set fname="%%~ff"
      echo !fdate! !fsize! !fname!
      )
    )
  endlocal & goto :EOF
The output might be
  C:\_D\TEST>cmdfaq
  20.05.2006 10:10      21928 "C:\_D\TEST\BATFAQ2.BAT"
  20.05.2006 10:19        372 "C:\_D\TEST\CMDFAQ.CMD"

A related problem asked in alt.mdsosbatch.nt. Suppose there is a
file C:\WHEREVER\LIST.TXT containing a list of file names such as
  C:\_D\TEST\TEST!.TXT
  C:\_D\TEST\TEST%.TXT

To perform an example operation on those files use the following
kind of syntax
  @echo off & setlocal enableextensions disabledelayedexpansion
  for /f "tokens=*" %%f in ("c:\wherever\list.txt") do type "%%f"
  endlocal & goto :EOF

Also see item #146 and item #47.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:22 2011
Subject: 142) How to extract the filename from the end of an URL reference?
Date: Mon, 31 Jan 2011 01:02:22
From: ts@uwasa.fi (Timo Salmi)

There are several ways of doing this. Consider the following example
where the URL is http://lipas.uwasa.fi/~ts/http/netiquet.html
The easiest of the solutions, posted by Ted Davis et al. is

  @echo off & setlocal enableextensions
  set url_=http://lipas.uwasa.fi/~ts/http/netiquet.html
  for %%a in (%url_%) do set filename_=%%~nxa
  echo %filename_%
  endlocal & goto :EOF
The output would be
  C:\_D\TEST>cmdfaq
  netiquet.html

Note that if there are spaces (not a good idea in an URL), the URL
has to be enclosed in quotes.

There is an interesting corollary. The method can also be used to
get the last word on a line. For example
  @echo off & setlocal enableextensions
  set line_=Hello World and Ted Davis
  for %%a in (%line_%) do set line_=%%~nxa
  echo %line_%
  endlocal & goto :EOF
will give
  C:\_D\TEST>cmdfaq
  Davis

However, consider
  @echo off & setlocal enableextensions
  set line_=Hello World and Harlan Grove.
  for %%a in (%line_%) do set line_=%%~a
  echo %line_%
  for %%a in (%line_%) do set line_=%%~nxa
  echo %line_%
  endlocal & goto :EOF
Note the differences in the output
  C:\_D\TEST>cmdfaq
  Grove.
  Grove

References/Comments:
 http://www.google.com/groups?selm=447e0ff0%240%2422334%249b536df3%40news.fv.fi
 http://www.google.com/groups?selm=vgds729t5hg6nfpb9ef3f5fos15q533olq%404ax.com
 http://www.google.com/groups?selm=1149140236.288371.157450%40g10g2000cwb.googlegroups.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:23 2011
Subject: 143) How do I get the current time zone in a script?
Date: Mon, 31 Jan 2011 01:02:23
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  :: Get the time zone in minutes
  for /f "tokens=5" %%a in (
    'w32tm /tz^|find "Time zone"') do set TZbias=%%a
  for /f "tokens=1 delims=m" %%a in (
    'echo %TZbias%') do set TZbias=%%a
  ::
  :: Display the result in minutes
  echo Bias: %TZbias% minutes
  ::
  :: Display the result in hours
  set /a TZfrac=%TZbias%%%60*100/60
  if %TZfrac% LSS 0 set /a TZfrac=-%TZfrac%
  set /a TZbias=-%TZbias%/60
  echo UTC+(%TZbias%.%TZfrac%)
  endlocal & goto :EOF

The output for my own computer's time zone (Europe/Helsinki) is
  C:\_D\TEST>cmdfaq
  Bias: -120 minutes
  UTC+(2.0)

Alternatively, in XP and beyond
  @echo off & setlocal enableextensions
  for /f "tokens=* skip=1" %%i in ('wmic OS Get CurrentTimeZone') do (
    set CurrentTimeZone_=%%i)
  echo CurrentTimeZone: %CurrentTimeZone_% minutes
  endlocal & goto :EOF

The output for my own computer's time zone (Europe/Helsinki) in the
summer is
  C:\_D\TEST>cmdfaq
  CurrentTimeZone: 180               minutes

Another method:
  @echo off & setlocal enableextensions
  for /f "tokens=2,*" %%i in ('systeminfo^|findstr /b "Time Zone:"') do (
    set tz_=%%j)
  echo %tz_%
  for /f "tokens=1" %%i in ('echo "%tz_%"') do set tz_=%%~i
  set tz_=%tz_:(=%
  set tz_=%tz_:)=%
  echo %tz_%
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  (GMT+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius
  GMT+02:00

Using JavaScript in WSH
  @echo off & setlocal enableextensions
  set js_=%temp%\tmp$$$.js
  >"%js_%" echo WScript.Echo(new Date().getTimezoneOffset());
  for /f %%a in ('cscript //nologo "%js_%"') do (
    set TZbias=%%a)
  for %%f in ("%js_%") do if exist %%f del "%%f"
  echo TZbias=%TZbias%
  endlocal & goto :EOF

The output for my own computer's time zone (Europe/Helsinki) in the summer is
  C:\_D\TEST>cmdfaq
  TZbias=-180

A Visual Basic Script (VBScript) aided command line script solution
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  for /f "tokens=1-2" %%a in ('cscript //nologo "%vbs_%"') do (
    set TZbias=%%a
    set TZdaylightBias=%%b)
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  :: Display the time zone offsets from Greenwich mean time
  echo TZbias=%TZbias%
  echo TZdaylightBias=%TZdaylightBias%
  ::
  endlocal & goto :EOF
  '
  'The Visual Basic Script 'VBS
  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 'VBS
  Set colTimeZone = objWMIService.ExecQuery("Select * from Win32_TimeZone") 'VBS
  For Each objTimeZone in colTimeZone 'VBS
    Wscript.Echo objTimeZone.Bias & " " & objTimeZone.DaylightBias 'VBS
  Next 'VBS

The output for my own computer's time zone (Europe/Helsinki) in the
summer is
  C:\_D\TEST>cmdfaq
  TZbias=120
  TZdaylightbBias=-60

Caveat: The item delves into whatever information the XP computer
offers under the hood. The interpretation of the terminology and the
usage of the results is up to the user, since mine is a scripting FAQ,
not a calendar intricacies treatise.

References/Comments:
 http://technet2.microsoft.com/windowsserver/en/library/b43a025f-cce2-4c82-b3ea-3b95d482db3a1033.mspx
 http://www.merlyn.demon.co.uk/batfiles.htm
 https://www.microsoft.com/technet/scriptcenter/scripts/os/dates/default.mspx
 http://www.google.com/groups?selm=ZJlaBMXjhL9JFwkg%40invalid.uk.co.demon.merlyn.invalid
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:24 2011
Subject: 144) How do I parse the items from a path like C:\a\b\c\d ?
Date: Mon, 31 Jan 2011 01:02:24
From: ts@uwasa.fi (Timo Salmi)

Also see the similar items
  40} How to get the number of and parse the arguments given to a script?
  80} How can I extract the last part of a path such as C:\ABC\DEF\GHI\?
 115} How can I decompose the path to be one folder per line?

Edited from the original question by Bob Altman in
alt.msdos.batch.nt

I call a batch file like this:  DoSomething c:\a\b\c\d
I need to parse the specified path and execute a command for each
folder in the path containing the specified file.  The order of
execution doesn't matter.  So, for the above example, I need to do
the following:
  SomeCommand c:\a
  SomeCommand c:\a\b
  SomeCommand c:\a\b\c

With a generic rather than customized parsing view we can use e.g.
  @echo off & setlocal enableextensions enabledelayedexpansion
  set var=C:\a\b\c\d
  rem the above might alternatively be:
  rem set var=%~1
  ::
  :: Parse
  set count_=0
  set rest_=%var%
  :_loop
  for /f "tokens=1* delims=\" %%a in ("%rest_%") do (
    set /a count_+=1
    set var[!count_!]=%%a
    set rest_=%%b
    if defined rest_ goto _loop
    )
  ::
  :: Display the individual parts
  for /l %%i in (1,1,%count_%) do echo var[%%i]=!var[%%i]!
  echo.
  ::
  :: Display combined
  for /l %%i in (1,1,%count_%) do (
    set composite_=!composite_!!var[%%i]!\
    if %%i GTR 1 echo Whatever !composite_:~0,-1!
    )
  ::
  endlocal & goto :EOF

The output would be
  C:\_D\TEST>cmdfaq
  var[1]=C:
  var[2]=a
  var[3]=b
  var[4]=c
  var[5]=d

  Whatever C:\a
  Whatever C:\a\b
  Whatever C:\a\b\c
  Whatever C:\a\b\c\d

Note how the solution also gives the method for counting the number
of words in a variable or on a line
  @echo off & setlocal enableextensions
  set var=%~1
  ::
  :: Parse and count
  set count_=0
  set rest_=%var%
  :_loop
  for /f "tokens=1*" %%a in ("%rest_%") do (
    set /a count_+=1
    set rest_=%%b
    if defined rest_ goto _loop
    )
  ::
  :: Display the result
  echo.%var%
  echo The number of words is %count_%
  endlocal & goto :EOF

For example
  C:\_D\TEST>cmdfaq "Asterisk means the remaining text on the line"
  Asterisk means the remaining text on the line
  The number or words is 8

The solution also gives the method to get the last word of a line:
  @echo off & setlocal enableextensions
  set var=%~1
  ::
  :: Parse
  set rest_=%var%
  :_loop
  for /f "tokens=1*" %%a in ("%rest_%") do (
    set rest_=%%b
    set last_=%%a
    if defined rest_ goto _loop
    )
  ::
  :: Display the result
  echo.%var%
  echo The last word is "%last_%"
  endlocal & goto :EOF

For example
  C:\_D\TEST>cmdfaq "Asterisk means the remaining text on the line"
  Asterisk means the remaining text on the line
  The last word is "line"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:25 2011
Subject: 145) How to find out if WinXP SP2 is installed via a script?
Date: Mon, 31 Jan 2011 01:02:25
From: ts@uwasa.fi (Timo Salmi)

With systeminfo:
  @echo off & setlocal enableextensions
  systeminfo | findstr /b "OS.*Pack.2" && echo SP2 installed
  endlocal & goto :EOF
The output would be something like
  C:\_D\TEST>cmdfaq
  OS Version:                5.1.2600 Service Pack 2 Build 2600
  SP2 installed

Or, more generally
  @echo off & setlocal enableextensions
  systeminfo|findstr /b "OS.Version.*Pack"
  for /f "tokens=4-6" %%a in ('
    systeminfo^|findstr /b "OS.Version.*Pack"') do (
      set spver_=%%a %%b %%c)
  echo spver_=%spver_%
  endlocal & goto :EOF

The output would be something like
  C:\_D\TEST>cmdfaq
  OS Version:                5.1.2600 Service Pack 2 Build 2600
  spver_=Service Pack 2
or
  C:\_D\TEST>cmdfaq
  OS Version:                5.1.2600 Service Pack 3 Build 2600
  spver_=Service Pack 3

The information can also be obtained from the registry
  @echo off & setlocal enableextensions
  ::
  :: Get the Operating System
  for /f "tokens=2,*" %%i in (
  'reg query "HKLM\software\microsoft\windows nt\currentversion" /v ProductName^
    ^| find "REG_SZ"') do set prod_=%%j
  echo.%prod_%
  ::
  :: Get the service pack version
  for /f "tokens=2,*" %%i in (
  'reg query "HKLM\software\microsoft\windows nt\currentversion" /v CSDVersion^
    ^| find "REG_SZ"') do (
    set pack_=%%j)
  echo.%pack_%
  endlocal & goto :EOF

The output would be something like
  C:\_D\TEST>cmdfaq
  Microsoft Windows XP
  Service Pack 2

Alternatively
  @echo off & setlocal enableextensions
  ::
  :: Get the Operating System
  for /f "tokens=2,*" %%i in (
  'reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName^
    ^| find "REG_SZ"') do set prod_=%%j
  echo.%prod_%
  ::
  :: Get the service pack version
  for /f "tokens=2,*" %%i in (
    'reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CSDVersion^
    ^| find "REG_SZ"') do (
    set pack_=%%j)
  echo.%pack_%
  endlocal & goto :EOF

Another method, in XP and beyond is to use WMIC (Windows Management
Instrumentation Command-Line Utility). This, however, is a bit more
drastic requiring administrator status.
  @echo off & setlocal enableextensions
  for /f "tokens=* skip=1" %%i in ('wmic OS Get CSDVersion') do (
    set pack_=%%i)
  echo.%pack_%
  endlocal & goto :EOF

The output would be something like
  C:\_D\TEST>cmdfaq
  Service Pack 2

Or
  @echo off & setlocal enableextensions
  for /f "tokens=* skip=1" %%i in ('wmic OS Get ServicePackMajorVersion') do (
    set packMajor_=%%i)
  for /f "tokens=* skip=1" %%i in ('wmic OS Get ServicePackMinorVersion') do (
    set packMinor_=%%i)
  echo.%packMajor_: =%.%packMinor_: =%
  endlocal & goto :EOF

The output would be something like
  C:\_D\TEST>cmdfaq
  2.0

Another, VBS-aided solution:
  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  for /f %%a in ('cscript //nologo "%vbs_%"') do set pack_=%%a
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  echo pack_=%pack_%
  ::
  endlocal & goto :EOF
  '
  'The Visual Basic Script 'VBS
  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 'VBS
  Set colOSes = objWMIService.ExecQuery ("Select * from Win32_OperatingSystem") 'VBS
  For Each objOS in colOSes 'VBS
    WScript.Echo objOS.ServicePackMajorVersion & "." & objOS.ServicePackMinorVersion 'VBS
  Next 'VBS

The output would be something like
  C:\_D\TEST>cmdfaq
  pack_=2.0

References/Comments:
 http://www.google.com/groups?selm=t3dcd21657sj9jrilgqvdmdbmgsdliskq2%404ax.com
 http://technet.microsoft.com/en-us/library/bb742610.aspx
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:26 2011
Subject: 146) Using delayed expansion for giving variable values as arguments
Date: Mon, 31 Jan 2011 01:02:26
From: ts@uwasa.fi (Timo Salmi)

Consider the following snippet
  @echo off & setlocal enableextensions
  rem        0123456789
  set string=abcdefghij
  echo %string%
  echo %string:~2,4%
  endlocal & goto :EOF
As we well know the will result in the following where the substring
starts from the position 1+2 (the string numbering starts from 0, see
SET /?) and is four characters long.
  C:\_D\TEST>cmdfaq
  abcdefghij
  cdef

Next consider
  @echo off & setlocal enableextensions enabledelayedexpansion
  set i=2&set j=4
  echo %i% %j%
  rem        0123456789
  set string=abcdefghij
  echo %string%
  echo !string:~%i%,%j%!
  endlocal & goto :EOF
The output will be
  C:\_D\TEST>cmdfaq
  2 4
  abcdefghij
  cdef

An alternative solution, not needing explicit delayed extension, is
  @echo off & setlocal enableextensions disabledelayedexpansion
  set i=2&set j=4
  echo %i% %j%
  rem        0123456789
  set string=abcdefghij
  echo %string%
  call set s_=%%string:~%i%,%j%%%
  echo %s_%
  echo.
  endlocal & goto :EOF
The output will be exactly the same. The advantage of this alternative
is that exclamation marks can appear as part of the string. For example
  @echo off & setlocal enableextensions disabledelayedexpansion
  set i=2&set j=4
  echo %i% %j%
  rem        0123456789
  set string=abc!efghij
  echo %string%
  call set s_=%%string:~%i%,%j%%%
  echo %s_%
  echo.
  endlocal & goto :EOF
will give
  C:\_D\TEST>cmdfaq
  2 4
  abc!efghij
  c!ef

Just for the sake of demonstration we also could as well use a
subroutine
  @echo off & setlocal enableextensions disabledelayedexpansion
  set i=2&set j=4
  echo %i% %j%
  rem        0123456789
  set string=abc!efghij
  echo %string%
  call :EchoSubString "%string%" %i% %j%
  endlocal & goto :EOF
  ::
  :EchoSubString
  @echo off & setlocal enableextensions
  set s_=%~1
  call echo %%s_:~%2,%3%%
  endlocal & goto :EOF
Also this will give
  C:\_D\TEST>cmdfaq
  2 4
  abc!efghij
  c!ef

For more examples see e.g. items #40, #96, #132 and #141.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:27 2011
Subject: 147) What was the time 100 minutes ago?
Date: Mon, 31 Jan 2011 01:02:27
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  rem The 24h time format is assumed
  rem as always is sensible in an international setting
  ::
  :: Get the current time: hour and minutes
  for /f "tokens=1,2 delims=:" %%a in ('time /t') do (
    set hhNow_=%%a
    set mmNow_=%%b
    )
  :: Remove any leading zeros to avoid the octal trap
  for /f "tokens=* delims=0" %%a in ('echo %hhNow_%') do set hhNow_=%%a
  for /f "tokens=* delims=0" %%b in ('echo %mmNow_%') do set mmNow_=%%b
  ::
  :: Current time in minutes since midnight
  set /a mmSinceMidnight=60*%hhNow_%+%mmNow_%
  ::
  :: Display
  echo hhNow_ %hhNow_%
  echo mmNow_ %mmNow_%
  echo mmSinceMidnight %mmSinceMidnight%
  ::
  :: How many minutes to calculate backwards?
  set back_=0
  set rollover=
  set OutOfRange=
  if not "%~1"=="" set back_=%1
  if %back_% GTR 1440 set OutOfRange=true
  if %back_% LSS    0 set OutOfRange=true
    if defined OutOfRange (
      echo Parameter %back_% out of range
      goto :EOF
      )
    )
  ::
  :: How many minutes since midnight was back_ minutes ago?
  set /a backSinceMidnight=%mmsinceMidnight%-%back_%
  if %backSinceMidnight% LSS 0 (
    set /a backSinceMidnight=%backSinceMidnight%+24*60
    set rollover=true
    )
  :: Display
  echo backSinceMidnight %backSinceMidnight%
  ::
  :: Convert the result to hours and minutes
  set /a hhBack_=%backSinceMidnight%/60
  set /a mmBack_=%backSinceMidnight%-60*%hhBack_%
  ::
  :: Display
  echo hhBack_ %hhBack_%
  echo mmBack_ %mmBack_%
  if defined rollover echo Yesterday
  ::
  endlocal & goto :EOF

The output e.g.
  C:\_D\TEST>cmdfaq 100
  hhNow_ 9
  mmNow_ 33
  mmSinceMidnight 573
  backSinceMidnight 473
  hhBack_ 7
  mmBack_ 53

The VBScript-aided solution is much more clearcut. And it spans
midnights without any further measures:
  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (
    echo Usage: "%~0" MinutesToAdd
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  ::
  findstr "'%skip%VBS1" "%~f0" > "%vbs_%"
  for /f "tokens=*" %%a in ('cscript //nologo "%vbs_%"') do (
    set DateTimeNow=%%a)
  ::
  findstr "'%skip%VBS2" "%~f0" > "%vbs_%"
  for /f "tokens=*" %%a in ('
    cscript //nologo "%vbs_%" "%~1" "%DateTimeNow%"') do (
      set DateTimeThen=%%a)
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  echo DateTimeNow =%DateTimeNow%
  echo DateTimeThen=%DateTimeThen%
  ::
  endlocal & goto :EOF
  '
  'The First Visual Basic Script
  FixedNow=Now 'VBS1
  Wscript.Echo FixedNow 'VBS1
  '
  'The Second Visual Basic Script
  Set arg = WScript.Arguments 'VBS2
  Wscript.Echo DateAdd("n", CLng(arg(0)), arg(1)) 'VBS2

The output could be e.g.
  C:\_D\TEST>cmdfaq -100
  DateTimeNow =17.04.2009 01:23:03
  DateTimeThen=16.04.2009 23:43:03

Should you wish to get the date and time elements into separate
environment variables the solution is
  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (
    echo Usage: "%~0" MinutesToAdd
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  ::
  findstr "'%skip%VBS1" "%~f0" > "%vbs_%"
  for /f "tokens=*" %%a in ('cscript //nologo "%vbs_%"') do (
    set DateTimeNow=%%a)
  ::
  findstr "'%skip%VBS2" "%~f0" > "%vbs_%"
  for /f "tokens=1-6" %%a in ('
    cscript //nologo "%vbs_%" "%~1" "%DateTimeNow%"') do (
      set yyyy_=%%a
      set mm_=%%b
      set dd_=%%c
      set hh_=%%d
      set nn_=%%e
      set ss_=%%f)
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  ::
  echo DateTimeNow =%DateTimeNow%
  echo yyyy_=%yyyy_%
  echo mm_=%mm_%
  echo dd_=%dd_%
  echo hh_=%hh_%
  echo nn_=%nn_%
  echo ss_=%ss_%
  ::
  endlocal & goto :EOF
  '
  'The First Visual Basic Script
  FixedNow=Now 'VBS1
  Wscript.Echo FixedNow 'VBS1
  '
  'The Second Visual Basic Script
  Set arg = WScript.Arguments 'VBS2
  NewDatetime = DateAdd("n", Eval(arg(0)), arg(1)) 'VBS2
  Wscript.StdOut.Write (DatePart("yyyy",NewDateTime)) & " " 'VBS2
  Wscript.StdOut.Write Right(0 & DatePart("m",NewDateTime), 2) & " " 'VBS2
  Wscript.StdOut.Write Right(0 & DatePart("d",NewDateTime), 2) & " " 'VBS2
  Wscript.StdOut.Write Right(0 & DatePart("h",NewDateTime), 2) & " " 'VBS2
  Wscript.StdOut.Write Right(0 & DatePart("n",NewDateTime), 2) & " " 'VBS2
  Wscript.StdOut.WriteLine Right(0 & DatePart("s",NewDateTime), 2) 'VBS2

The output could be e.g.
  C:\_D\TEST>cmdfaq -100
  DateTimeNow =17.04.2009 01:23:03
  yyyy_=2009
  mm_=04
  dd_=16
  hh_=23
  nn_=43
  ss_=03

Another example of the output (get a year from now)
  C:\_D\TEST>cmdfaq 365*24*60
  DateTimeNow =09.05.2009 11:44:31
  yyyy_=2010
  mm_=05
  dd_=09
  hh_=11
  nn_=44
  ss_=31
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:28 2011
Subject: 148) How to calculate the day-of-year number with a pure cmd script?
Date: Mon, 31 Jan 2011 01:02:28
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions disabledelayedexpansion
  if "%~3"=="" (
    echo Usage: %~0 DD MM YYYY
    echo No leading zeros!
    goto :EOF)
  ::
  :: Get the date
  set day=%~1
  set month=%~2
  set year=%~3
  ::
  :: Call the day ordinal number subroutine
  call :JDdayNumber %day% %month% %year% DayOrdinalNumber
  ::
  :: Display the result
  echo %day%.%month%.%year% Day ordinal number %DayOrdinalNumber%
  endlocal & goto :EOF
  ::
  :: ============================================================
  :: Subroutine: Calculate a day's ordinal number within the year
  :JDdayNumber day month year return_
  setlocal enableextensions enabledelayedexpansion
  if %2 LEQ 2 (
    set /a f=%1-1+31*^(%2-1^)
    ) else (
    set /a a=%3
    set /a b=!a!/4-!a!/100+!a!/400
    set /a c=^(!a!-1^)/4-^(!a!-1^)/100+^(!a!-1^)/400
    set /a s=!b!-!c!
    set /a f=%1+^(153*^(%2-3^)+2^)/5+58+!s!
    )
  set /a return_=%f%+1
  endlocal & set "%4=%return_%" & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq 17 9 2006
  17.9.2006 Day ordinal number 260

(Also see DATEINFO.CMD)

An alternative, more concise formulation of the ordinal day subroutine
  ::
  :: ============================================================
  :: Subroutine: Calculate a day's ordinal number within the year
  :: Based on a posting by Herbert Kleebauer
  :JDdayNumber d m y w
  setlocal enableextensions disabledelayedexpansion
  set /a w= %1 +(!(%3 %% 4)-!(%3 %% 100)+!(%3 %% 400))*(!((%2-3)^&16))
  set /a w=(%w%+(%2-1)*30+2*(!((%2-7)^&16))-1+((65611044^>^>(2*%2))^&3))
  endlocal & set "%4=%w%" & goto :EOF

In the above
  !  Unary NOT operator
  &  Bitwise AND
  %% Remainder (modulo) operator
  >> Logical shift

References/Comments:
 Also see item #70.
 http://www.tondering.dk/claus/cal/node8.html#SECTION00880000000000000000
 http://www.google.com/groups?selm=45015682.E2869E86%40unibwm.de
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:29 2011
Subject: 149) How to calculate a date's week number with a pure cmd script?
Date: Mon, 31 Jan 2011 01:02:29
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions disabledelayedexpansion
  if "%~3"=="" (
    echo Usage: %~0 DD MM YYYY
    echo No leading zeros!
    goto :EOF)
  ::
  :: Get the date
  set day=%~1
  set month=%~2
  set year=%~3
  ::
  :: Call the day ordinal number subroutine
  call :JDweekNumber %day% %month% %year% WeekNumber
  ::
  :: Display the result
  echo %day%.%month%.%year% Week number %WeekNumber%
  endlocal & goto :EOF
  ::
  :: =====================================
  :: Subroutine: Calculate the week number
  :: The weeks in the algorithm start on Mondays
  :JDweekNumber day month year return_
  setlocal enableextensions enabledelayedexpansion
  if %2 LEQ 2 (
    set /a a=%3-1
    set /a b=!a!/4-!a!/100+!a!/400
    set /a c=^(!a!-1^)/4-^(!a!-1^)/100+^(!a!-1^)/400
    set /a s=!b!-!c!
    set /a e=0
    set /a f=%1-1+31*^(%2-1^)
    ) else (
    set /a a=%3
    set /a b=!a!/4-!a!/100+!a!/400
    set /a c=^(!a!-1^)/4-^(!a!-1^)/100+^(!a!-1^)/400
    set /a s=!b!-!c!
    set /a e=!s!+1
    set /a f=%1+^(153*^(%2-3^)+2^)/5+58+!s!
    )
  set /a g=(%a%+%b%) %% 7
  set /a d=(%f%+%g%-%e%) %% 7
  set /a n=%f%+3-%d%
  set return_=
  if %n% LSS 0 set /a return_=53
  if %n% GTR 364+%s% set /a return_=1
  if not defined return_ set /a return_=%n%/7+1
  endlocal & set "%4=%return_%" & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq 17 9 2006
  17.9.2006 Week number 37
  C:\_D\TEST>cmdfaq 18 9 2006
  18.9.2006 Week number 38
Note that 17.9.2006 is a Sunday and 18.9.2006 a Monday.

If a Visual Basic Script (VBScript) aided command line script is
acceptable then
  @echo off & setlocal enableextensions
  if "%~3"=="" (
    echo Usage: %~0 DD MM YYYY
    goto :EOF)
  ::
  set day=%~1
  set month=%~2
  set year=%~3
  ::
  set vbs_=%temp%\tmp$$$.vbs
  echo Wscript.Echo DatePart("ww","%year%.%month%.%day%",vbMonday,vbFirstFourDays)>"%vbs_%"
  for /f %%w in ('cscript //nologo "%vbs_%"') do set wk_=%%w
  echo wk_=%wk_%
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF

(Also see DATEINFO.CMD)

References/Comments:
 http://www.tondering.dk/claus/cal/node8.html#SECTION00880000000000000000
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:30 2011
Subject: 150) How can I extract the http and ftp URL:s from an HTML file?
Date: Mon, 31 Jan 2011 01:02:30
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Get the name of the HTML file to be processed
  set Source=%~1
  if not defined Source (
    echo +----------------------------------------------------+
    echo ^| A script to get the HTTP, FTP and FILE links       ^|
    echo ^| from an HTML page soure file                       ^|
    echo ^| By Prof. Timo Salmi, Last modified Thu 15-Feb-2007 ^|
    echo +----------------------------------------------------+
    echo.
    echo Usage %~0 [HTMLSourceFilename]
    goto :EOF)
  if not exist "%Source%" (
    echo File "%Source%" not found
    goto :EOF)
  ::
  :: An auxiliary temporary file
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  for /f "tokens=*" %%f in ("%temp_%") do set temp_=%%~sf
  set tempfile=%temp_%\tempfile.tmp
  set tempfil2=%temp_%\tempfil2.tmp
  for %%f in (%tempfile% %tempfil2%) do if exist %%f del %%f
  ::
  :: Substitute = with , since tokens does not work with =
  :: Customize the delim character if necessary
  set delim=,
  for /f "tokens=*" %%c in ('type "%Source%"') do (
    set lineContents=%%c
    echo !lineContents:"=%delim%!
    )>>%tempfile%
  ::
  :: Find the HTTP links
  for /f "tokens=2 delims=%delim%" %%a in ('
    find /i "HREF=%delim%http://" %tempfile%') do (
      echo %%a
      )>>%tempfil2%
  type %tempfil2%|find /i "http://"
  ::
  :: Find the FILE links
  for /f "tokens=2 delims=%delim%" %%a in ('
    find /i "HREF=%delim%file://" %tempfile%') do (
      echo %%a
      )>>%tempfil2%
  type %tempfil2%|find /i "file://"
  ::
  :: Find the FTP links
  for /f "tokens=2 delims=%delim%" %%a in ('
    find /i "HREF=%delim%ftp://" %tempfile%') do (
      echo %%a
      )>>%tempfil2%
  type %tempfil2%|find /i "ftp://"
  ::
  :: Clean up
  for %%f in (%tempfile% %tempfil2%) do if exist %%f del %%f
  endlocal & goto :EOF

The output from my own home page's source would start with
  http://www.uwasa.fi/
  http://lipas.uwasa.fi/~ts/timo97.html
  http://www.uwasa.fi/laskentatoimi/
  http://www.uwasa.fi/kauppatieteet/
  http://www.uwasa.fi/
  http://www.vaasa.fi/
  http://en.wikipedia.org/wiki/Finland
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:31 2011
Subject: 151) Extract the lines of a text file from between two marker-lines?
Date: Mon, 31 Jan 2011 01:02:31
From: ts@uwasa.fi (Timo Salmi)

> I have a text file that is like:
>
> date = OCT0606
> asdf
> sdaf
> asdfasdgsdgh
> asdfsdfasdg
> START-OF-DATA
> asdfasdfg
> asdfgdfgsfg
> sadfsdfgsa
> asdfgsdfg
> END-OF-DATA
> asdfgalsdkdfklmlkm
> asdfgasdfg
>
> I need to clear everything from this file except the data between
> the START-OF-DATA and END-OF-DATA using a batch file.

  @echo off & setlocal enableextensions enabledelayedexpansion
  set source=C:\_M\MyData.txt
  set flagStart=
  set flagEnd=
  for /f %%a in ('type "%source%"') do (
    echo %%a|find "START-OF-DATA">nul
    if !errorlevel! EQU 0 set flagStart=true
    echo %%a|find "END-OF-DATA">nul
    if !errorlevel! EQU 0 set flagEnd=true
    if defined flagStart if not defined FlagEnd (
      echo %%a|find /v "START-OF-DATA"
      )
    )
  endlocal & goto :EOF

Actually the lines
  set flagStart=
  set flagEnd=
are superfluous, but they depict the logic.

The output
  C:\_D\TEST>cmdfaq
  asdfasdfg
  asdfgdfgsfg
  sadfsdfgsa
  asdfgsdfg

Also as below. The first is inclusive, the second exclusive
  sed -n "/START-OF-DATA/,/END-OF-DATA/p" %source%
  sed "1,/START-OF-DATA/d" %source%|sed "/END-OF-DATA/,$d"

The problem can also be solved with a command-line driven VBScript filter:
  @echo off & setlocal enableextensions
  ::
  :: Your parameters
  set myfile_=C:\_M\MyData.txt
  set cut1=START-OF-DATA
  set cut2=END-OF-DATA
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%cut1%" "%cut2%" < "%myfile_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  set arg = WScript.Arguments 'VBS
  startTrigger = arg(0) 'VBS
  endTrigger = arg(1) 'VBS
  '
  startFound = False 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    line = WScript.StdIn.ReadLine 'VBS
    If InStr (1,line,endTrigger,vbTextCompare) > 0 Then Exit Do 'VBS
    If startFound Then WScript.StdOut.WriteLine line 'VBS
    If InStr (1,line,startTrigger,vbTextCompare) > 0 Then startFound = True 'VBS
  Loop 'VBS

References/Comments:
 http://www.google.com/groups?selm=BIyWg.8911%24TV3.4248%40newssvr21.news.prodigy.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:32 2011
Subject: 152) How can I remove all !:s and &:s from a text file with a script?
Date: Mon, 31 Jan 2011 01:02:32
From: ts@uwasa.fi (Timo Salmi)

Special characters among &()[]{}^=;!'+,`~ in a text file may cause
problems when the text file is processed with a CLI script. A SED
solution can be used:
  sed -e "s/[\x21\x26]//g" C:\_M\MyText.txt
The character code values are in hexadecimal. Given a text file like
  Hello World & others! Scripting is fun!
the output would be
 Hello World  others Scripting is fun

Another situation applying SED. Say that you wished to substitute
all the @ characters with %40 in a file. Then
  @echo off
  sed -e "s/@/%%40/g" C:\_M\MyText.txt
Note the doubles in %%40 when within a script.

A Visual Basic Script (VBScript) aided solution can be used so that
third party utilities are not needed
  @echo off & setlocal enableextensions
  rem C:\_M\TEST\CMDTEST.CMD
  ::
  set myfile_=C:\_M\TEST\My Test File.txt
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  <"%myfile_%" cscript //nologo "%vbs_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    str = Replace (str, "&","") 'VBS
    str = Replace (str, "!","") 'VBS
    WScript.StdOut.WriteLine str 'VBS
  Loop 'VBS

C:\_M\TEST>type "My Test File.txt"
  This & is ! line & 1
  This & is ! line & 2
  "& and ! this & is ! line 3"

C:\_M\TEST>cmdtest
  This is line 1
  This is line 2
  " and this is line 3"

One further question (also see item #34). How does one include
removing quotes (") in the above VBS solution? One has to use the
(decimal) Chr function:
  @echo off & setlocal enableextensions
  rem C:\_M\TEST\CMDTEST.CMD
  ::
  set myfile_=C:\_M\TEST\My Test File.txt
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  <"%myfile_%" cscript //nologo "%vbs_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    str = WScript.StdIn.ReadLine 'VBS
    str = Replace (str, "&","") 'VBS
    str = Replace (str, "!","") 'VBS
    str = Replace (str, Chr(34),"") 'VBS
    WScript.StdOut.WriteLine str 'VBS
  Loop 'VBS

C:\_M\TEST>cmdtest
  This  is  line  1
  This  is  line  2
  and  this  is  line 3
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:33 2011
Subject: 153) How do I test if my Internet connection to an IP is working?
Date: Mon, 31 Jan 2011 01:02:33
From: ts@uwasa.fi (Timo Salmi)

There are so many different ways of writing a code. Here is one of
the many alternatives in XP
   @echo off & setlocal enableextensions
   set ok_=true
   ping -n 1 %1|find "Lost = 0">nul||set ok_=
   if defined ok_ (
    echo You have an active connection to %1
    ) else (
    echo You have NO active connection to %1
    )
   endlocal & goto :EOF
Output
  C:\_D\TEST>cmdfaq www.google.com
  You have an active connection to www.google.com

However, since ping returns an errorlevel directly, at least in XP,
one can also write
   @echo off & setlocal enableextensions
   ping -n 1 194.109.6.66>nul
   if %errorlevel% EQU 0 (
    echo You have an active connection to the internet
    ) else (
    echo You have NO active connection to the internet
    )
   endlocal & goto :EOF

Alternatively, just
  @echo off & setlocal enableextensions
  (ping %1>nul && echo Success) || echo Failure
  endlocal & goto :EOF

Output
  C:\_D\TEST>cmdfaq www.google.com
  Success
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:34 2011
Subject: 154) How do I remove leading zeros from a string with script only?
Date: Mon, 31 Jan 2011 01:02:34
From: ts@uwasa.fi (Timo Salmi)

Removing leading zeros, spaces or whatever from a string is somewhat
different from removing the leading zeros from an unsigned integer
explained in FAQ item #119 "How can I remove any leading zeros from
an unsigned integer?" Also, this time we would wish not to use any
third party programs like sed as in the FAQ item #79 "How can I trim
leading and trailing spaces?"

Also note that any zeros within the string should not be removed,
only the leading ones! (Removing all the zeros would be trivial
using the %var:0=% substitution.)

  @echo off & setlocal enableextensions
  set oldValue=00this is a 0 test
  call :RemoveLeadingZeros "%oldValue%" newValue
  echo "%oldValue%"
  echo "%newValue%"
  endlocal & goto :EOF
  ::
  :RemoveLeadingZeros
  setlocal enabledelayedexpansion
  set s=%~1
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si (
      if not "!si!"=="0" set Flag=true
      if defined Flag set return_=!return_!!si!
      )
    )
  endlocal & set "%2=%return_%" & goto :EOF

The output should and will be
  C:\_D\TEST>cmdfaq
  "00this is a 0 test"
  "this is a 0 test"

Let's consider an application for this method from an adapted
question posed in alt.msdos.batch.nt. Suppose that there are files
like the following in a folder
  00000001.TIF
  00000002.TIF
  00000003.TIF
  :
  00000010.TIF
  00000011.TIF
and we wish to rename those files to be without the leading zeros.
The script can then be written (with echo as a safety) as
  @echo off & setlocal enableextensions enabledelayedexpansion
  for /f "tokens=* delims=" %%f in ('dir /s /b /a:-d-s-h 0*.TIF') do (
    set oldFullPathAndFileName=%%~dpnxf
    set oldFileName=%%~nxf
    call :RemoveLeadingZeros "!oldFileName!" fileNameWithoutZeros
    echo ren "!oldFullPathAndFileName!" "!fileNameWithoutZeros!"
    )
  ::
  endlocal & goto :EOF
  ::
  :RemoveLeadingZeros
  setlocal
  set s=%~1
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si (
      if not "!si!"=="0" set Flag=true
      if defined Flag set return_=!return_!!si!
      )
    )
  ::
  endlocal & set "%2=%return_%" & goto :EOF

The output will be:
  C:\_D\TEST>cmdfaq
  ren "C:\_D\TEST\00000001.tif" "1.tif"
  ren "C:\_D\TEST\00000002.tif" "2.tif"
  ren "C:\_D\TEST\00000003.tif" "3.tif"
  :
  ren "C:\_D\TEST\00000010.tif" "10.tif"
  ren "C:\_D\TEST\00000011.tif" "11.tif"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:35 2011
Subject: 155) How can I use command-line to open a Windows Explorer window?
Date: Mon, 31 Jan 2011 01:02:35
From: ts@uwasa.fi (Timo Salmi)

The simplest format is just
  explorer

To open a window view with the current file selected
  @echo off & setlocal enableextensions
  explorer /select,"%~f0"
  endlocal & goto :EOF

To open multiple windows use e.g.
  @echo off & setlocal enableextensions
  explorer /select,"%~f0"
  explorer /select,"C:\_D\TEST\CMDFAQ2.CMD"
  endlocal & goto :EOF

E.g. the following command
  Explorer /n,"C:\Documents and Settings"
will open a normal folder window view to C:\Documents and Settings
  Explorer /e,/select,C:\WINDOWS\system32\cmd.exe
will open an extended folder window with cmd.exe selected.

There is a twist. What if you wish to open a zip-file in an explorer window?
  C:\>rundll32.exe zipfldr.dll,RouteTheCall C:\_M\TestFolder\pakettig.zip

References/Comments:
 http://support.microsoft.com/kb/314853/en-us
 http://support.microsoft.com/kb/307856/en-us
 http://support.microsoft.com/kb/555305/en-us
 http://support.microsoft.com/kb/152457
 http://www.google.com/groups?selm=gf7n94t82do879op3j919rr8h5r361ve7k%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:36 2011
Subject: 156) How does one create a shortcut using the command-line?
Date: Mon, 31 Jan 2011 01:02:36
From: ts@uwasa.fi (Timo Salmi)

"Create a shortcut from the command line, K.Yabumoto Pixelab"
See the references.

References/Comments:
 http://www.xxcopy.com/xxcopy38.htm
 ftp://garbo.uwasa.fi/win95/dosshell/xxmklink.zip
 http://www.google.com/groups?selm=epak2l.3f8.1%40news.tacke.de
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:37 2011
Subject: 157) How to get the count of words and the last word of a variable?
Date: Mon, 31 Jan 2011 01:02:37
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  set var=This is my test
  call :GetLast "%var%" lastword nr
  ::
  :: Display the result
  echo.%var%
  echo The number of words is %nr%
  echo The last word is "%lastword%"
  endlocal & goto :EOF
  ::
  :GetLast
  setlocal
  set rest_=%~1
  :_loop
  for /f "tokens=1*" %%a in ("%rest_%") do (
    set /a count_+=1
    set rest_=%%b
    set last_=%%a
    if defined rest_ goto _loop
    )
  endlocal & set "%2=%last_%" & set "%3=%count_%" & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  This is my test
  The number of words is 4
  The last word is "test"

Note the following, obvious twist
  @echo off & setlocal enableextensions
  set var=This is, my test
  call :GetLast "%var%" lastword nr
  ::
  :: Display the result
  echo.%var%
  echo The number of words is %nr%
  echo The last word is "%lastword%"
  endlocal & goto :EOF
  ::
  :GetLast
  setlocal
  set rest_=%~1
  :_loop
  for /f "tokens=1* delims=," %%a in ("%rest_%") do (
    set /a count_+=1
    set rest_=%%b
    set last_=%%a
    if defined rest_ goto _loop
    )
  endlocal & set "%2=%last_%" & set "%3=%count_%" & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq
  This is, my test
  The number of words is 2
  The last word is " my test"

Consider an application with several twists. A user wrote (suitably
edited here) in alt.msdos.batch.nt

I (the said user) have this On_Call.txt file with the following
information
  22.01.2007     John Doe           John.doe@mytest.com
  9991234567@mytest.com
  22.01.2007     Yo C.J. Joe         Yo.Joe@mytest.com
  9991236789@mytest.com
  29.01.2007     Mary Jane         Mary.Jane@mytest.com
  9994567890@mytest.com
  29.01.2007     John Jon            John.jon@mytest.com
  9997890123@mytest.com
  05.02.2007     Tina Turner       Tina.Turner@mytest.com
  9998901234@mytest.com
  05.02.2007     Ike Turner         Ike.Turner@mytest.com
  9999012345@mytest.com

I need help with a script to read this file and only pull the email
address and pager number and write them or export to another file
based on the date. I have two files called email.txt which only has
email address and pager.txt that has only the pager number it.
Incidently, the above file is automatically generated by another
system and saved as a text file in the above format.

So lets say that today is 22.01.2007, the script would run and only
export from the above file John.doe@mytest.com and Yo.Joe@mytest.com
and write them to the email.txt file and then take the pager numbers
9991234567@mytest.com and 9991236789@mytest.com and write them to
the pager.txt file.

This is Timo's solution
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Delete the old situation, if need be. Else not.
  if exist email.txt del email.txt
  if exist pager.txt del pager.txt
  ::
  set today=%date%
  for /f "tokens=*" %%a in ('type On_Call.txt') do (
    set /a count+=1
    set /a mod=!count!%%2
    if !mod! EQU 1 (
      set entireline=%%a
      set flag=
      for /f "tokens=1" %%a in ('echo !entireline!') do (
        if "%%a"=="%today%" set flag=true
        )
      if defined flag (
        call :GetLast "!entireline!" lastword
        echo !lastword!
        )>>email.txt
      )
    if defined flag if !mod! EQU 0 echo %%a>>pager.txt
    )
  ::
  :: Display the results
  type email.txt
  echo.
  type pager.txt
  endlocal & goto :EOF
  ::
  :: The subroutine for getting the last item on a line
  :GetLast
  setlocal
  set rest_=%~1
  :_loop
  for /f "tokens=1*" %%a in ("%rest_%") do (
    set rest_=%%b
    set last_=%%a
    if defined rest_ goto _loop
    )
  endlocal & set "%2=%last_%" & goto :EOF

The test output
  C:\_M>test.cmd
  John.doe@mytest.com
  Yo.Joe@mytest.com

  9991234567@mytest.com
  9991236789@mytest.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:38 2011
Subject: 158) Why won't the statements within my if condition work properly?
Date: Mon, 31 Jan 2011 01:02:38
From: ts@uwasa.fi (Timo Salmi)

There are several examples throughout this FAQ about for loops which
require delayed expansion. The need for delayed expansion is,
however, not limited to for-loops. Below is an artificial example
reminding the reader that the operations within an if statement have
the same feature:

  @echo off & setlocal enableextensions
  set par1=%1
  if "%par1%"=="a" (
    set par2=%2
    echo %par2%
    )
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>cmdfaq a b c d
  ECHO is off.

However, written appropriately
  @echo off & setlocal enableextensions enabledelayedexpansion
  set par1=%1
  if "%par1%"=="a" (
    set par2=%2
    echo !par2!
    )
  endlocal & goto :EOF
the output will be what one rather would want:
  C:\_D\TEST>cmdfaq a b c d
  b

The latter could, of course, also be written as
  @echo off & setlocal enableextensions disabledelayedexpansion
  set par1=%1
  if not "%par1%"=="a" goto next1
    set par2=%2
    echo %par2%
  :next1
  endlocal & goto :EOF

Next, consider a practical example which involves multiple related
aspects including for-loops, if-statements and testing errorlevels.
The task is to test the integrity of a set of .zip files. The
following code will tell whether they all pass, or if any number of
them includes errors.
  @echo off & setlocal enableextensions enabledelayedexpansion
  set unzipProg=C:\_F\TOOLS\PKUNZIP.EXE
  set error_=
  for %%f in ("C:\_E\TSZIP\*.ZIP") do (
    "%unzipProg%" -t "%%f">nul
    if !errorlevel! GTR 0 set error_=true)
  if defined error_ (
    echo Error^(s^) in at least one of the browsed .zip files
    ) else (
    echo No errors in the browsed .zip files)
  endlocal & goto :EOF

References/Comments:
 http://blogs.msdn.com/oldnewthing/archive/2006/08/23/714650.aspx
 SET /?
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:39 2011
Subject: 159) How do I test that a name does not contain lowercase letters?
Date: Mon, 31 Jan 2011 01:02:39
From: ts@uwasa.fi (Timo Salmi)

Let's limit the lowercase letters to the English alphabet a-z only.

  @echo off & setlocal enableextensions
  set name_=%~1
  if "%name_%"=="" (
    echo Usage: [NameToBeChecked]
    goto :EOF
    )
  ::
  echo %name_%|findstr "[abcdefghijklmnopqrstuvwxyz]">nul
  if %errorlevel% EQU 0 (
    echo The name "%name_%" is not uppercase only
    ) else (
    echo The name "%name_%" is uppercase only)
  endlocal & goto :EOF

Examples of the output
  C:\_D\TEST>cmdfaq "My Test File.txt"
  The name "My Test File.txt" is not uppercase only

  C:\_D\TEST>cmdfaq "MY TEST"
  The name "MY TEST" is uppercase only

There is a catch in using findstr regular expressions. In the above
FINDSTR "[a-z]" would not work as expected from the common regular
expressions definitions. The set option [a-z] seems to case
insensitive in the XP command line interface!

The central line of the task could be written in a "one-liner" style
as follows
  @echo off & setlocal enableextensions
  set name_=%~1
  if "%name_%"=="" (
    echo Usage: [NameToBeChecked]
    goto :EOF)
  ::
  echo %name_%|findstr "[abcdefghijklmnopqrstuvwxyz]">nul&&echo Not upcase||echo Upcase
  endlocal & goto :EOF

Examples of the output
  C:\_D\TEST>cmdfaq "My Test File.txt"
  Not upcase

  C:\_D\TEST>cmdfaq "MY TEST"
  Upcase

Run the command following && only if the command preceding the symbol
is successful.
Run the command following || only if the command preceding || fails.

What if we wish to list the UPPERCASE-only files in a folder?
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: "%~f0" "FolderName"
    goto :EOF)
  if not exist "%~1\" (
    echo Folder "%~1" not found ^(or is a file^)
    goto :EOF)
  pushd "%~1\"
  for /f "tokens=*" %%f in ('
    dir /a:-d /b^|findstr /v "[abcdefghijklmnopqrstuvwxyz]"') do (
      call :DisplayDateSizeName "%%~ff")
  popd
  endlocal & goto :EOF
  ::
  :DisplayDateSizeName
  set filename_="%~f1"
  set filesize_=          %~z1
  set filesize_=%filesize_:~-10%
  echo %~t1 %filesize_% "%~1"
  goto :EOF
Part of the output could be e.g.
  06.06.1998 06:18        334 "TESTADD.BAT"
  04.06.1998 09:31        146 "TESTFNGT.BAS"
  07.11.2001 08:19       1462 "TIEDEKN.BAT"
  12.06.2008 01:24        594 "VBSFAQ.VBS"
  06.10.2007 08:28       4084 "VBSFAQ2.VBS"

References/Comments:
  hh ntcmds.chm::/ntcmds_shelloverview.htm
  hh ntcmds.chm::/findstr.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:40 2011
Subject: 160) How do I get a list of all my folders with and sorted by size?
Date: Mon, 31 Jan 2011 01:02:40
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Set the auxiliary file names
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  set FolderContent=%temp_%\FullContent.dir
  set SizeAndFolder=%temp_%\SizeAndFolder.dir
  set FolderList=%temp_%\FolderList.dir
  ::
  :: Make the folder list
  dir /s /-c "C:\" > "%FolderContent%"
  :: Traverse it
  findstr ".Directory.of. .File(s)." "%FolderContent%">"%SizeAndFolder%"
  set Flag=
  for /f "tokens=* delims= " %%a in (
    'type "%SizeAndFolder%"') do (
      if not defined Flag (
        set Folder=%%a
        set Flag=true
        ) else (
        set Size= %%a
        set Flag=
        echo !Size:~-20! !Folder!>>"%FolderList%"
        )
    )
  ::
  :: Show the result
  sort "%FolderList%"
  call :WarnIfExlamations
  ::
  :: Clean up
  for %%f in ("%FolderContent%" "%SizeAndFolder%" "%FolderList%") do (
    if exist %%f del %%f)
  endlocal & goto :EOF
  ::
  :: =======================================================
  :WarnIfExlamations
  setlocal enableextensions disabledelayedexpansion
  findstr "!" "%SizeAndFolder%">nul
  if %errorlevel% GTR 0 goto :EOF
  echo.
  echo Warning: Folder names with exclamation marks ^(!^) encountered
  endlocal & goto :EOF

The output might end with something like
     242904830 bytes Directory of C:\WINDOWS\system32\dllcache
     359978283 bytes Directory of C:\WINDOWS\$NtServicePackUninstall$
     429340336 bytes Directory of C:\WINDOWS\system32
     497131051 bytes Directory of C:\WINDOWS\ServicePackFiles\i386

Unfortunately, there is the familiar catch. Because of the enabled
delayedexpansion any exlamation marks (!) in the names will be dropped.

Note that the solution above gives the size of the immediate folder.
That is, the material in the subfolders does not accumulate in the
size of a folder. A different answer is gotten with a VBScript-aided
solution. If there are any subfolders in a folder, the material in the
subfolders is fully included in the upper-level folder's size
information. Furthermore, the VBS solution is not affected potential
exclamation marks in the folder names.
  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (echo Usage: %~f0 "[FolderName]"&goto :EOF)
  set debug_=true
  set debug_=
  ::
  :: Build a Visual Basic Script
  set skip=
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set vbs_=%temp_%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  if defined debug_ (
    type "%vbs_%"
    goto _cleanup)
  cscript //nologo "%vbs_%" "%~1"
  ::
  :_cleanup
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  '
  Function FolderSizeFn(folderspec) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(folderspec) 'VBS
    FolderSizeFn = f.size 'VBS
  End Function 'VBS
  '
  Function TraverseSubFolders(StartFolderName) 'VBS
    Dim fso, f, f1, sf 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(StartFolderName) 'VBS
    Set sf = f.SubFolders 'VBS
    For Each f1 in sf 'VBS
      Wscript.Echo PadSpFn(FolderSizeFn(f1),15) & " " & f1 'VBS
      TraverseSubFolders(f1) 'VBS
    Next 'VBS
  End Function 'VBS
  '
  Function TraverseStartFolder(StartFolderName) 'VBS
    Dim fso, f 'VBS
    Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
    Set f = fso.GetFolder(StartFolderName) 'VBS
    Wscript.Echo PadSpFN(FolderSizeFn(f),15) & " " & f 'VBS
  End Function 'VBS
  '
  Function PadSpFn (str, n) 'VBS
    PadSpFn = Right(String(n-1," ")&str,n) 'VBS
  End Function 'VBS ,
  '
  Set arg = WScript.Arguments 'VBS
  TraverseStartFolder(arg(0)) 'VBS
  TraverseSubFolders(arg(0)) 'VBS

An edited example of the output
C:\_D\TEST>cmdfaq C:\_F\TEXT\ | sort
              0 C:\_F\TEXT\PROFOS
           9770 C:\_F\TEXT\EMAIL
          11264 C:\_F\TEXT\INFO
         339548 C:\_F\TEXT\LIST
         486585 C:\_F\TEXT\PROFLT
         573877 C:\_F\TEXT\OTHERS\PUBLICAT
        2311953 C:\_F\TEXT\BYROK
       12779759 C:\_F\TEXT\OTHERS
       19349999 C:\_F\TEXT

Let's return to the original task of getting with pure script the size
of each folder counting only the size of files in it but not below the
folder. At the same time avoid the poison character problem. The
solution below does these, but it is very slow even on a fast computer.
  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (echo Usage: %~f0 "[FirstFolderName]"&goto :EOF)
  ::
  set tempdir_=%temp%\temp$$$.dir
  for %%f in ("%tempdir_%") do if exist %%f del %%f
  ::
  call :GetFolderSize "%~1">"%tempdir_%"
  for /f "tokens=*" %%a in ('dir /s /b /a:d "%~1"') do (
    call :GetFolderSize "%%a")>>"%tempdir_%"
  sort "%tempdir_%"
  ::
  for %%f in ("%tempdir_%") do if exist %%f del %%f
  endlocal & goto :EOF
  ::
  :: ====================================================
  :GetFolderSize
  setlocal enableextensions
  for /f "tokens=3" %%a in ('
    dir /-c "%~1"^|find " File(s) "') do (
      call :DisplayFolderInfo "%%a" "%~1")
  endlocal & goto :EOF
  ::
  :: ====================================================
  :DisplayFolderInfo
  setlocal enableextensions
  set var_=               %~1
  set var_=%var_:~-15%
  echo %var_% "%~2"
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq "C:\_K"
                0 "C:\_K"
                0 "C:\_K\test & dir!"
           370725 "C:\_K\CATEYE"
          1091783 "C:\_K\SCANOHJE"
          2578410 "C:\_K\TOPFIELD\NotOk"
          4228788 "C:\_K\PMAX"
          4875161 "C:\_K\TPLINK"
         10934167 "C:\_K\TOPFIELD"

Not that it makes any difference, but in the above
  ::
  call :GetFolderSize "%~1">"%tempdir_%"
  for /f "tokens=*" %%a in ('dir /s /b /a:d "%~1"') do (
    call :GetFolderSize "%%a")>>"%tempdir_%"
  sort "%tempdir_%"
  ::
could as well be written as
  ::
  call :GetFolderSize "%~1">"%tempdir_%"
  for /r "%~1" %%a in (.) do (
    call :GetFolderSize "%%a")>>"%tempdir_%"
  sort "%tempdir_%"
  ::

References/Comments:
 http://www.google.com/groups?selm=3tt2339hipbl4hvg3i5pbqo7v7n7qie3hr%404ax.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:41 2011
Subject: 161) How do I test that the Windows Script Host is available?
Date: Mon, 31 Jan 2011 01:02:41
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  echo Wscript.Echo "@set WSHavailable=1">"%temp%\test$$.vbs"
  cscript /nologo "%temp%\test$$.vbs" > "%temp%\test$$.bat"
  for %%c in (call del) do %%c "%temp%\test$$.bat"
  del "%temp%\test$$.vbs"
  if not "%WSHavailable%"=="1" (echo Windows Script Host is not not available & goto :EOF)
  echo Windows Script Host is available, continuing
  rem Whatever
  endlocal & goto :EOF

Or, simply
  @echo off & setlocal enableextensions
  cscript>nul
  if %errorlevel% NEQ 0 goto :EOF
  echo Windows Script Host is available, continuing
  rem Whatever
  endlocal & goto :EOF

Or even just
  @echo off & setlocal enableextensions
  cscript>nul||goto :EOF
  echo Windows Script Host is available, continuing
  rem Whatever
  endlocal & goto :EOF

Or, with a subroutine
  @echo off & setlocal enableextensions
  call :checkVBS status
  if not defined status (
    echo.&echo Windows Script Host is not not available, exiting
    goto :EOF)
  echo Continuing whatever
  endlocal & goto :EOF
  ::
  :: ==========================================================
  :: Subroutine: Check whether Windows Script Host is available
  :checkVBS
  setlocal enableextensions
    >"%temp%\tmp$$$.vbs" echo WScript.Echo "VBSfound"
    for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do (
      set found_=%%a>nul)
    for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  endlocal & set "%1=%found_%" & goto :EOF

The output might be:
  C:\_D\TEST>cmdfaq
  Continuing whatever
or
  C:\_D\TEST>cmdfaq
  'cscript' is not recognized as an internal or external command,
  operable program or batch file.
  Windows Script Host is not not available, exiting

References/Comments:
 http://www.google.com/groups?selm=y_j4j.50032%24eY.29616%40newssvr13.news.prodigy.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:42 2011
Subject: 162) Finding duplicate files in a directory tree
Date: Mon, 31 Jan 2011 01:02:42
From: ts@uwasa.fi (Timo Salmi)

See the responses to this posting
 http://www.google.com/groups?selm=HRG4j.72%24nQ3.42%40newsfe15.phx
in the thread
 http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/1279924b2f59fd4b
--------------------------------------------------------------------
From ts@uwasa.fi Mon Jan 31 01:02:43 2011
Subject: 163) How do I test and ensure that CRLF is the last char (pair) of my file?
Date: Mon, 31 Jan 2011 01:02:43
From: ts@uwasa.fi (Timo Salmi)

"I have a log file that may or may not end with a carriage return. How
can I test what the last character of the file is and insert a <CR><LF>
if needed?"

Why bother with the testing? Just always type (with for) the file
redirecting it to another file. For example
  @echo off & setlocal enableextensions
  if exist "%temp%\templog.lis" del "%temp%\templog.lis"
  for /f "tokens=*" %%a in ('type "C:\_M\My log file.txt"') do (
    echo %%a >>"%temp%\templog.lis")
  if exist "MyLogFile.txt" if exist "%temp%\templog.lis" del "MyLogFile.txt"
  move /-y "%temp%\templog.lis" "MyLogFile.txt"
  endlocal & goto :EOF
or
  @echo off & setlocal enableextensions
  set mylog_=C:\_M\My log file.txt
  if exist "%temp%\templog.lis" del "%temp%\templog.lis"
  more "%mylog_%">"%temp%\templog.lis"
  if exist "%mylog_%" if exist "%temp%\templog.lis" del "%mylog_%"
  move /-y "%temp%\templog.lis" "%mylog_%"
  endlocal & goto :EOF

Also see the somewhat similar item #139.

There are subtle differences between TYPE and MORE. Consider two text
files (where this first one's last line is missing
the customary <CR><LF> pair):

  @echo off & setlocal enableextensions
  for %%f in ("file*.txt") do type "%%f"
  endlocal & goto :EOF

The output will be:
  C:\TEST>CMDFAQ.CMD
  First line of file one
  Last line of file oneFirst line of file two

  @echo off & setlocal enableextensions
  for %%f in ("file*.txt") do more "%%f"
  endlocal & goto :EOF

The output will be:
  C:\TEST>CMDFAQ.CMD
  First line of file one
  Last line of file one
  First line of file two

Any of the above solves the problem, one way or another, but what if
one anyway is interested in getting the last character of a file? This
can be done e.g. with a Visual Basic Script (VBScript) aided command
line script:
  @echo off & setlocal enableextensions
  ::
  set myfile_=C:\_M\My log file.txt
  if not exist "%myfile_%" (
    echo File "%myfile_%" not found
    goto :EOF)
  ::
  :: Build a Visual Basic Script and run it
  set vbs_="%temp%\tmp$$$.vbs"
  set skip=
  findstr "'%skip%VBS" "%~f0" > %vbs_%
  for /f %%a in ('cscript //nologo %vbs_%') do (
    set lastcharcode=%%a)
  echo The lastcharcode for "%myfile_%" is %lastcharcode%
  ::
  :: Clean up
  for %%f in (%vbs_%) do if exist %%f del %%f
  ::
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim fso, f, myfile, filesize 'VBS
  Set WshShell = WScript.CreateObject("WScript.Shell") 'VBS
  myfile = WshShell.ExpandEnvironmentStrings("%myfile_%") 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  filesize = fso.GetFile(myfile).Size 'VBS
  Set f = fso.OpenTextFile(myfile, ForReading) 'VBS
  f.Skip(filesize-1) 'VBS
  WScript.Echo Asc(f.Read(1)) 'VBS
The output could be e.g.
  C:\_D\TEST>cmdfaq
  The lastcharcode for "C:\_M\My log file.txt" is 10

References/Comments:
 http://www.google.com/groups?selm=48416a63$0$5320$a82e2bb9%40reader.athenanews.com
 http://www.google.com/groups?selm=YP21k.2929$uE5.42%40flpi144.ffdc.sbc.com
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:44 2011
Subject: 164) How to concatenate (join/paste side by side) two files?
Date: Mon, 31 Jan 2011 01:02:44
From: ts@uwasa.fi (Timo Salmi)

Assume the following LFN-type test files:
My File 1.txt
  My File 1.txt Line 1
  My File 1.txt Line 2
  My File 1.txt Line 3
  My File 1.txt Line 4
  My File 1.txt Line 5

My File 2.txt
  My File 2.txt Line 1
  My File 2.txt Line 2
  My File 2.txt Line 3
  My File 2.txt Line 4

Using CONCAT.EXE "Join two text-files side by side" from tsfltc22.zip
  @echo off & setlocal enableextensions
  for /f "tokens=*" %%f in ("C:\_D\TEST\My File 1.txt") do set myfile1_=%%~sf
  for /f "tokens=*" %%f in ("C:\_D\TEST\My File 2.txt") do set myfile2_=%%~sf
  CONCAT %myfile1_% %myfile2_% /B2
  endlocal & goto :EOF

The output will be
  C:\_M>c:\_d\test\cmdfaq
  My File 1.txt Line 1  My File 2.txt Line 1
  My File 1.txt Line 2  My File 2.txt Line 2
  My File 1.txt Line 3  My File 2.txt Line 3
  My File 1.txt Line 4  My File 2.txt Line 4
  My File 1.txt Line 5

A VBScript-aided solution
  @echo off & setlocal enableextensions
  set myfile1_=C:\_D\TEST\My File 1.txt
  set myfile2_=C:\_D\TEST\My File 2.txt
  if not exist "%myfile1_%" (
    echo Exiting: File "%myfile1_%" not found
    goto :EOF)
  if not exist "%myfile2_%" (
    echo Exiting: File "%myfile2_%" not found
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%myfile2_%" "%myfile1_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%~f del %%~f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim fso, arg, f1, f2, line1, line2 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set arg = WScript.Arguments 'VBS
  Set f1 = fso.OpenTextFile(arg(0), ForReading) 'VBS
  Set f2 = fso.OpenTextFile(arg(1), ForReading) 'VBS
  Do While (Not f1.AtEndOfStream) Or (Not f2.AtEndOfStream) 'VBS
    line1 = "     " 'VBS
    If Not f1.AtEndOfStream Then 'VBS
      line1 = f1.ReadLine 'VBS
    End If 'VBS
    line2 = "" 'VBS
    If Not f2.AtEndOfStream Then 'VBS
      line2 = f2.ReadLine 'VBS
    End If 'VBS
    WScript.Echo line1 & " " & line2 'VBS
  Loop 'VBS

The output will be
  C:\_D\TEST>cmdfaq
  My File 2.txt Line 1 My File 1.txt Line 1
  My File 2.txt Line 2 My File 1.txt Line 2
  My File 2.txt Line 3 My File 1.txt Line 3
  My File 2.txt Line 4 My File 1.txt Line 4
       My File 1.txt Line 5

Now what if you wish to start the first file at the third, not the
first line? Better than trying to adjust the methods above, is first
separately to filter the first two lines from the first file to an
auxiliary file. For example see the method given in item #69.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:45 2011
Subject: 165) How do I get the date and time separators and the local formats?
Date: Mon, 31 Jan 2011 01:02:45
From: ts@uwasa.fi (Timo Salmi)

You may first wish to revisit item #1.

  @echo off & setlocal enableextensions
  set tmpfile_=%temp%\cmdfaq.tmp
  reg query "HKEY_CURRENT_USER\Control Panel\International">"%tmpfile_%"
  ::
  for /f "tokens=3" %%a in ('more "%tmpfile_%"^|find "sDate "') do (
    set sDate_=%%a)
  if defined sDate_ (
    echo sDate_=%sDate_%
    ) else (
    echo sDate_=Space or none)
  ::
  for /f "tokens=3" %%a in ('more "%tmpfile_%"^|find "sShortDate "') do (
    set sShortDate_=%%a)
  if defined sShortDate_ (
    echo sShortDate_=%sShortDate_%
    ) else (
    echo sShortDate_=none)
  ::
  for /f "tokens=3" %%a in ('more "%tmpfile_%"^|find "sTime "') do (
    set sTime_=%%a)
  if defined sTime_ (
    echo sTime_=%sTime_%
    ) else (
    echo sTime_=Space or none)
  ::
  for /f "tokens=3" %%a in ('more "%tmpfile_%"^|find "sTimeFormat "') do (
    set sTimeFormat_=%%a)
  if defined sTimeFormat_ (
    echo sTimeFormat_=%sTimeFormat_%
    ) else (
    echo sTimeFormat_=none)
  ::
  for %%f in ("%temfile_%") do if exist %%f del %%f
  endlocal & goto :EOF

The output might be e.g.
  C:\_D\TEST>cmdfaq
  sDate_=.
  sShortDate_=dd.MM.yyyy
  sTime_=:
  sTimeFormat_=HH:mm:ss
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:46 2011
Subject: 166) How to rename files with underscores instead of spaces?
Date: Mon, 31 Jan 2011 01:02:46
From: ts@uwasa.fi (Timo Salmi)

166) Substituting spaces with underscores in a folder's file names.

"Please, does anyone have a script I can run the a command prompt that
will cycle thru the files in the current directory and rename files
with spaces to files with _?"

There may be more concise ways, but this is more generic and more
tolerant of the potential poison characters.
  @echo off & setlocal enableextensions
  set targetFolder=C:\Whatever
  pushd "%targetFolder%"
  for /f "tokens=*" %%f in ('
    dir /b /a-d-s "%targetFolder%\* *.*"') do (
      call :ProcessOneFile "%%~ff")
  popd
  endlocal & goto :EOF
  ::
  :ProcessOneFile
  setlocal enableextensions disabledelayedexpansion
    set filename="%~nx1"
    set filename=%filename: =_%
    echo ren %1 %filename%
  endlocal & goto :EOF

The output might look something like
  ren "C:\Whatever\My test file.txt" "My_test_file.txt"
  ren "C:\Whatever\My test file2.txt" "My_test_file2.txt"
  ren "C:\Whatever\Test & (5!).txt" "Test_&_(5!).txt"

1) The pushd/popd-pair ensures that the file path is correct when the
   /b switch is used in the dir. (Else it will be the the script's,
   which might be different.)
2) The /a-d switch sees to not renaming folders.
3) Remove the echo when you are sure that the solution is what you
   want.

A more condensed, slightly cryptic solution:
  @echo off & setlocal enableextensions
  set targetFolder=C:\Whatever
  pushd "%targetFolder%"
  for /f "tokens=*" %%f in ('
    dir /b /a-d-s "%targetFolder%\* *.*"') do (
      set "_=%%~nxf"
      call echo ren "%%~ff" "%%_: =_%%"
      )
  popd
  endlocal & goto :EOF

A much trickier situation arises if we wish to replace the dots ( . )
in a file name with underscores ( _ ). With the natural exception of
the one preceding the file's extension. Such a task is best handled
with a Visual Basic Script (VBScript) aided command line script.
  @echo off & setlocal enableextensions
  set targetFolder=C:\_M
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%targetFolder%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  '
  Set arg = WScript.Arguments 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  Set f = fso.GetFolder(arg(0)) 'VBS
  Set fc = f.Files 'VBS
  For Each f1 in fc 'VBS
    basename = fso.GetBaseName(f1) 'VBS
    If InStr (basename, ".") Then 'VBS
      extension = fso.GetExtensionName(f1) 'VBS
      s = "rem @ren " & Chr(34) & arg(0) & "\" 'VBS
      s = s & basename & "." & extension & Chr(34) 'VBS
      newbasename = Replace(basename, ".", "_") 'VBS
      s = s & " " & Chr(34) & newbasename 'VBS
      s = s & "." & extension & Chr(34) 'VBS
      Wscript.Echo s 'VBS
    End If 'VBS
  Next 'VBS

Given
  C:\_M>dir /a:-d /b
  My test file.txt
  My.&(!).test.txt
  This.is.a.test.txt

The safety output would be
  C:\_M>c:\_d\test\cmdfaq
  rem @ren "C:\_M\My.&(!).test.txt" "My_&(!)_test.txt"
  rem @ren "C:\_M\This.is.a.test.txt" "This_is_a_test.txt"

 Q: I receive mainframe files and I'm trying to remove the extra
periods in the filename since my script isn't picking them up. Or even
replacing the periods with "_" like FC.HIST.20080910.TXT to
FC_HIST_20080910.TXT

P.S. I'd prefer DOS commands for this. Please no VBS, etc.

First off, as seen in the above it would be the most robust and
flexible way. Nevertheless:

As you will have observed, there have been several interesting
suggestions to your question in the alt.msdos.batch newsgroup.
However, I would be very careful with the direct ren one- liners. It
is very easy to tangle the names hopelessly because of the circularity
danger. Much safer to take the more cautions slightly more cumbersome
route. But if you still prefer the ren one-liners, at the very least
first back up your files, or apply those solutions on a copied set.

If you do not have poison characters in your file names, here is one
prudent pure-batch approach demonstrated
  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  set targetFolder=C:\_M\TEST
  ::
  :: Make a test file set
  if not exist "%targetFolder%\" mkdir "%targetFolder%"
  >"%targetFolder%\FC.HIST.20080910.TXT" echo Test file 1
  >"%targetFolder%\FC.HIST.20080930.TXT" echo Test file 2
  >"%targetFolder%\FC.HIST.20081001a.TXT" echo Test file 3
  >"%targetFolder%\My test file.txt" echo Test file 4
  dir "%targetFolder%"
  echo.
  ::
  pushd "%targetFolder%"
  for /f "tokens=*" %%f in ('
    dir /b /a-d-s "%targetFolder%\*.txt"') do (
      call :ProcessOneFile "%%~ff")
  popd
  endlocal & goto :EOF
  ::
  :ProcessOneFile
  setlocal enableextensions disabledelayedexpansion
    set basename=%~n1
    set basename=%basename:.=_%
    set filename=%basename%%~x1
    echo ren %1 "%filename%"
  endlocal & goto :EOF

The output would be

  C:\_D\TEST>cmdfaq
   Volume in drive C is
   Volume Serial Number is

   Directory of C:\_M\TEST

  04.10.2008  21:20                13 FC.HIST.20080910.TXT
  04.10.2008  21:20                13 FC.HIST.20080930.TXT
  04.10.2008  21:20                13 FC.HIST.20081001a.TXT
  04.10.2008  21:20                13 My test file.txt
                 4 File(s)             52 bytes
                 0 Dir(s)  229,559,308,288 bytes free

  ren "C:\_M\TEST\FC.HIST.20080910.TXT" "FC_HIST_20080910.TXT"
  ren "C:\_M\TEST\FC.HIST.20080930.TXT" "FC_HIST_20080930.TXT"
  ren "C:\_M\TEST\FC.HIST.20081001a.TXT" "FC_HIST_20081001a.TXT"
  ren "C:\_M\TEST\My test file.txt" "My test file.txt"

Should one wish to remove the underscore ( _ ) after HIST, substitute
  :ProcessOneFile
  setlocal enableextensions disabledelayedexpansion
    set basename=%~n1
    set basename=%basename:.=_%
    set basename=%basename:HIST_=HIST%
    set filename=%basename%%~x1
    echo ren %1 "%filename%"
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=qv3cuh9s47l3.igjdi2t166us$.dlg%4040tude.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:47 2011
Subject: 167) How do I find out who is logged on the system?
Date: Mon, 31 Jan 2011 01:02:47
From: ts@uwasa.fi (Timo Salmi)

There is a special freeware third-party utility PsLoggedOn on PsTools by
Mark Russinovich available from Microsoft TechNet Windows Systinternals.

To some extent the following pure script solution can be used to
emulate UNIX who
  @echo off & setlocal enableextensions
  for /f "tokens=7 delims=," %%a in ('
    tasklist /v /fo csv^|
      findstr /i /c:"explorer.exe"') do (
        echo %%~a)
  endlocal & goto :EOF

The output could be e.g.
  C:\MyXPSCRIPTS>who
  ULPU\tsneti
  ULPU\Guest

Solved slightly differently
@echo off & setlocal enableextensions
for /f "tokens=3* delims=: " %%a in ('
  tasklist /v /fi "ImageName eq explorer.exe" /fo list^|
    find /i "User Name: "') do echo.%%a
endlocal & goto :EOF

The method can also be used as a first attempt to find out what
program is currently accessing (and thus locking) a particular file.
For example:
  C:\_M>del tscmd167.pdf
  C:\_M\TSCMD167.PDF
  The process cannot access the file because it is being used by another process.

  C:\_M>tasklist /v /fo csv|findstr /i /c:"tscmd167.pdf"
  "AcroRd32.exe","5524","Console","0","31180 K","Running","HUPU\ts","0:00:00","TSCMD167.PDF - Adobe Reader"

The fields in the above are
  "Image Name","PID","Session Name","Session#","Mem Usage","Status","User Name","CPU Time","Window Title"
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:48 2011
Subject: 168) How do I invoke Safely Remove Hardware using a cmd script
Date: Mon, 31 Jan 2011 01:02:48
From: ts@uwasa.fi (Timo Salmi)

Usually the notification area includes an icon for the task

However, that icon sometimes disappears. In that case safely to remove
hardware, and to get the icon back, you can use
  @echo off & setlocal enableextensions
  echo RunDll32.exe shell32.dll,Control_RunDLL hotplug.dll
  set ask_=
  set /p ask_="Run this script to Safely Remove Hardware [N/y]?"
  if /i "%ask_%"=="n" goto :EOF
  if /i "%ask_%"=="" goto :EOF
  if /i not "%ask_%"=="y" goto _ask
  RunDll32.exe shell32.dll,Control_RunDLL hotplug.dll
  endlocal & goto :EOF

Similar references/comments:
 https://forums.microsoft.com/TechNet/ShowPost.aspx?PostID=3947907&SiteID=17
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:49 2011
Subject: 169) How to set the time server from cmd and how to synchronize the clock?
Date: Mon, 31 Jan 2011 01:02:49
From: ts@uwasa.fi (Timo Salmi)

Caveats:
   1. It is assumed that the PC is not in a domain with a domain's own
      centralized time server.
   2. Some of the steps may be superfluous.

  @echo on & @setlocal enableextensions
  @echo =========================
  @echo Turn off the time service
  net stop w32time
  @echo ======================================================================
  @echo Set the SNTP (Simple Network Time Protocol) source for the time server
  net time /setsntp:time.nist.gov,0x1
  @echo =============================================
  @echo ... and then turn on the time service back on
  net start w32time
  @echo =============================================
  @echo Tell the time sync service to use the changes
  w32tm /config /update
  @echo ===========================================
  @echo Display the currently configured NTP server
  net time /querysntp
  @echo =======================================================
  @echo Reset the local computer's time against the time server
  w32tm /resync /rediscover
  @endlocal & @goto :EOF

The output could be e.g.:
  C:\_D\TEST>cmdfaq
  =========================
  Turn off the time service
  C:\_D\TEST>net stop w32time
  The Windows Time service is stopping.
  The Windows Time service was stopped successfully.
  ======================================================================
  Set the SNTP (Simple Network Time Protocol) source for the time server
  C:\_D\TEST>net time /setsntp:time.nist.gov,0x1
  The command completed successfully.
  =============================================
  ... and then turn on the time service back on
  C:\_D\TEST>net start w32time
  The Windows Time service is starting.
  The Windows Time service was started successfully.
  =============================================
  Tell the time sync service to use the changes
  C:\_D\TEST>w32tm /config /update
  The command completed successfully.
  ===========================================
  Display the currently configured NTP server
  C:\_D\TEST>net time /querysntp
  The current SNTP value is: time.nist.gov,0x1
  The command completed successfully.
  =======================================================
  Reset the local computer's time against the time server
  C:\_D\TEST>w32tm /resync /rediscover
  Sending resync command to local computer...
  The command completed successfully.

If the Windows time service refuses to co-operate it may be necessary
to give it a heftier wake-up call:
  @echo off & setlocal enableextensions
  net stop w32time
  w32tm.exe /unregister
  w32tm.exe /unregister
  w32tm /register
  net start w32time
  endlocal & goto :EOF
The output could be e.g.
  C:\_D\TEST>cmdfaq
  The Windows Time service is stopping.
  The Windows Time service was stopped successfully.
  The following error occurred: Access is denied. (0x80070005)
  W32Time successfully registered.
  W32Time successfully registered.
  The Windows Time service is starting.
  The Windows Time service was started successfully

References/Comments: See http://www.netikka.net/tsneti/info/tscmd169.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:50 2011
Subject: 170) How do I get the total size of a volume, not just the available space?
Date: Mon, 31 Jan 2011 01:02:50
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  :: Which drive? Define in here or as a parameter to the script
  set drive_=C:
  if not "%~1"=="" set drive_=%~1
  ::
  :: Build a Visual Basic Script
  set skip=
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set vbs_=%temp_%\tmp$$$.vbs
  >"%vbs_%" findstr "'%skip%VBS" "%~f0"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  for /f "tokens=1-3 delims= " %%a in (
    'cscript //nologo "%vbs_%" "%drive_%"') do (
      set totalSizeBytes_=%%a
      set totalSizeMB_=%%b
      set totalSizeGB_=%%c)
  If "%totalSizeBytes_%"=="NotReady" (echo %drive_% not ready&goto :_out)
  If "%totalSizeBytes_%"=="NotFound" (echo %drive_% not found&goto :_out)
  echo %drive_% %totalSizeBytes_% bytes
  echo %drive_% %totalSizeMB_% MB
  echo %drive_% %totalSizeGB_% GB
  ::
  :: Clean up
  :_out
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  Set arg = WScript.Arguments 'VBS
  Set fso = CreateObject("Scripting.FileSystemObject") 'VBS
  If fso.DriveExists(arg(0)) Then 'VBS
      Set d = fso.GetDrive(fso.GetDriveName(arg(0))) 'VBS
      If d.IsReady Then 'VBS
        s = d.TotalSize 'VBS
        s = s & " " & Int(d.TotalSize/1024/1024) 'VBS
        s = s & " " & Round(d.TotalSize/1024/1024/1024,2) 'VBS
        WScript.Echo s 'VBS
      Else 'VBS
        WScript.Echo "NotReady" 'VBS
      End If 'VBS
    Else 'VBS
      WScript.Echo "NotFound" 'VBS
  End If 'VBS

The output could be e.g.
  C:\_D\TEST>cmdfaq
  C: 250056704000 bytes
  C: 238472 MB
  C: 232.88 GB
or
  C:\_D\TEST>cmdfaq E:
  E: not ready
or
  C:\_D\TEST>cmdfaq F:
  F: not found


Another method, but it requires a local NTFS volume and the FSUTIL
utility requires that you have administrative privileges. (As an
unrelated aside notice the trick of dividing a FOR command on several
lines.)

  @echo off & setlocal enableextensions
  set drive_=C:
  if not "%~1"=="" set drive_=%~1
  ::
  for /f "tokens=2 delims=:" %%a in (
    'fsutil volume diskfree %drive_%^|
      findstr /i /c:"Total # of bytes"') do (
        set totalSizeBytes_=%%a)
  if defined totalSizeBytes_ echo %drive_% %totalSizeBytes_% bytes
  if not defined totalSizeBytes_ echo %drive_% The size could not be resolved
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq
  C: 250056704000 bytes

One way of getting the same information in Windows XP for tallying is
start
  Accessories
    System Tools
      System Information (or C:\WINDOWS\system32\dllcache\msinfo32.exe)
          Components
            Storage
              Drives (see Size)

Furthermore, diskpart (requiring administrative privileges) can be
used to see the volume information. Since the volume labels could be
missing and/or the types could vary from user to user, the rest is
left up to the user (see the discussion on the second reference).

References/Comments:
 http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/29341a09350a1b74/774b98d5276b5632#774b98d5276b5632
 http://www.google.com/groups?selm=1ad9psdkkugpm$.176fwec29msiu.dlg%4040tude.net
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:51 2011
Subject: 171) How do I get a list of all the PC's folders with the attributes indicated?
Date: Mon, 31 Jan 2011 01:02:51
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  for /f "tokens=* delims=" %%f in ('dir /a:d /b /s "C:\"') do attrib "%%~f"
  endlocal & goto :EOF

A prohibitive amount of output may be produced. You might wish to take on a suitable subset.
  @echo off & setlocal enableextensions
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set output_=%temp_%\foldlist.tmp
  for %%f in ("%output_%") do if exist %%f del %%f
  for /f "tokens=* delims=" %%f in ('
    dir /a:d /b /s "C:\Documents and Settings\Default User\My Documents"') do (
      attrib "%%~f">>"%output_%")
  more "%output_%"
  for %%f in ("%output_%") do if exist %%f del %%f
  endlocal & goto :EOF

A similar task. List with all the attributes the read-only folders on the PC.
  @echo off & setlocal enableextensions
  for /f "tokens=* delims=" %%f in ('
    dir /a:r /b /s "C:\"') do (
      if exist "%%~f\" attrib "%%~f")
  endlocal & goto :EOF
The output might be something like
     R     C:\Program Files
    HR     C:\Documents and Settings\All Users\Application Data
     R     C:\Documents and Settings\All Users\Documents
     R     C:\Documents and Settings\All Users\Start Menu
     R     C:\Documents and Settings\All Users\Documents\My Music
     R     C:\Documents and Settings\All Users\Documents\My Pictures
     R     C:\Documents and Settings\All Users\Documents\My Videos
     R     C:\Documents and Settings\All Users\Documents\My Music\Sample Music
     :
     R     C:\WINDOWS\Web\Wallpaper
     R     C:\_M\Testing & more
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:52 2011
Subject: 172) How to change and restore the title bar text of the command prompt?
Date: Mon, 31 Jan 2011 01:02:52
From: ts@uwasa.fi (Timo Salmi)

Setting the window title for the command prompt window in a script is
straight-forward:
 @echo off & setlocal enableextensions
 title A title for the command prompt window
 endlocal & goto :EOF

So far, so good. But what if we wish only a temporary title for the
duration of running a script?
  @echo off & setlocal enableextensions
  cmd /c title A transient caption
  rem Next do whatever
  echo Take a look at the title bar
  rem Wait for a moment
  ping -n 5 127.0.0.1>nul
  endlocal & goto :EOF

There is another option, but you'll the have to call the script with
cmd /k sciptname and terminate afterwards with exit.
  @echo off & setlocal enableextensions
  title A transient title
  rem Next do whatever
  echo Take a look at the title bar
  endlocal & goto :EOF

/c "Carries out the command specified by string and then terminates"
/k "Carries out the command specified by string but remains"

The START command has similar connotations, but it is covered in
item #36.

References/Comments:
  hh ntcmds.chm::/cmd.htm
  hh ntcmds.chm::/start.htm
  hh ntcmds.chm::/title.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:53 2011
Subject: 173) How do I get the original GUI path since CLI's may be changed?
Date: Mon, 31 Jan 2011 01:02:53
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  :: System-wide
  for /f "tokens=2,*" %%a in ('
    reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\"
      ^|findstr "Path"^|findstr "REG_EXPAND_SZ"') do echo %%b
  echo.
  :: User specific
  for /f "tokens=2,*" %%a in ('
    reg query "HKEY_CURRENT_USER\Environment\"
      ^|findstr "PATH"^|findstr "REG_EXPAND_SZ"') do echo %%b
  endlocal & goto :EOF

References/Comments:
 http://www.google.com/groups?selm=gn1pi9$lan$1%40news.motzarella.org
 http://support.microsoft.com/kb/310519
 http://vlaurie.com/computers2/Articles/environment.htm
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:54 2011
Subject: 174) How to write a script to launch a URL invoking the default browser?
Date: Mon, 31 Jan 2011 01:02:54
From: ts@uwasa.fi (Timo Salmi)

In brief, e.g.
  @echo off & setlocal enableextensions
  start "" "http://www.netikka.net/tsneti/info/tscmd.php"
  endlocal & goto :EOF
In the above the browser that is invoked depends on which file type is
associated with the .php extension. For example

We could also write
  @echo off & setlocal enableextensions
  set target_=http://www.netikka.net/tsneti/info/tscmd.php
  "%ProgramFiles%\Mozilla Firefox\firefox.exe" -requestPending -osint -url "%target_%"
  endlocal & goto :EOF
or for the Internet Explorer
  @echo off & setlocal enableextensions
  set target_=http://www.netikka.net/tsneti/info/tscmd.php
  "%ProgramFiles%\Internet Explorer\iexplore.exe" "%target_%"
  endlocal & goto :EOF
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:55 2011
Subject: 175) How do I get the current video display resolution?
Date: Mon, 31 Jan 2011 01:02:55
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  :: Build a Visual Basic Script
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run the script with Microsoft Windows Script Host Version 5.6
  for /f "tokens=1,2" %%a in ('cscript //nologo "%vbs_%"') do (
    set width_=%%a
    set height_=%%b)
  ::
  :: Display the results
  echo width_=%width_%
  echo height_=%height_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  if not defined cmdbox if defined PauseIfFromDesktop pause
  endlocal & goto :EOF
  '
  On Error Resume Next 'VBS
  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 'VBS
  Set colItems = objWMIService.ExecQuery ("Select * from Win32_DisplayConfiguration") 'VBS
  For Each objItem in colItems 'VBS
    WScript.StdOut.Write objItem.PelsWidth 'VBS
    WScript.StdOut.Write " " & objItem.PelsHeight 'VBS
    WScript.StdOut.WriteLine 'VBS
  Next 'VBS

The output could be e.g.
  C:\_D\TEST>CMDFAQ.CMD
  width_=1440
  height_=900

References/Comments:
 http://www.microsoft.com/technet/scriptcenter/scripts/hardware/display/hwdivb02.mspx
--------------------------------------------------------------------
From ts@uwasa.fi Mon Jan 31 01:02:56 2011
Subject: 176) How to get the rest of the command line parameters?
Date: Mon, 31 Jan 2011 01:02:56
From: ts@uwasa.fi (Timo Salmi)

The solution already is embedded in some other problem solutions in
this FAQ collection. However, it is given here as a separate item to
focus on the current question only. You may also wish to see e.g.
item #40.
  @echo off & setlocal enableextensions
  for /f "tokens=1*" %%a in ('echo.%*') do set rest_=%%b
  echo rest_=%rest_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_M>C:\_D\TEST\CMDFAQ.CMD 1 2 "3 & 3.5" 4
  rest_=2 "3 & 3.5" 4
or
  C:\_M>C:\_D\TEST\CMDFAQ.CMD 1
  rest_=
The echo. prevents confusion in the latter output example.

As an aside note in the demonstration below how a shift command has no
effect on the %* modifier that represents all the arguments passed to
the script.
  @echo off & setlocal enableextensions
  shift
  rem This is not affected
  for /f "tokens=1*" %%a in ('echo.%*') do set rest_=%%b
  echo rest_=%rest_%
  rem This is affected
  echo %%~2="%~2"
  endlocal & goto :EOF

The output could be e.g.
  C:\_M>C:\_D\TEST\CMDFAQ.CMD 1 2 "3 & 3.5" 4
  rest_=2 "3 & 3.5" 4
  %~2="3 & 3.5"
--------------------------------------------------------------------
From ts@uwasa.fi Mon Jan 31 01:02:57 2011
Subject: 177) How can I retrieve the target of a shortcut into a variable?
Date: Mon, 31 Jan 2011 01:02:57
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: "%~n0" ["The link's full path"]
    goto :EOF)
  ::
  if /i "%~x1" NEQ ".lnk" (
    echo Not a shortcut
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS1" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  :: Allow for hyphens (') in the target file names
  for /f "usebackq tokens=* delims=" %%a in (
    `cscript //nologo "%vbs_%" "%~1"`) do set target_=%%a
  ::
  :: Display the result
  echo "%~1"
  echo links to
  echo "%target_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  Set WshShell = WScript.CreateObject("WScript.Shell") 'VBS1
  Set arg = WScript.Arguments 'VBS1
  Set oShellLink = WshShell.CreateShortcut(arg(0)) 'VBS1
  WScript.Echo oShellLink.TargetPath 'VBS1

The output could be e.g.
  C:\_D\TEST>cmdfaq "C:\_L\TIMO\EXTENS03\EXCELVB.TXT.lnk"
  "C:\_L\TIMO\EXTENS03\EXCELVB.TXT.lnk"
  links to
  "C:\_D\EXCEL\EXCELVB.TXT"

If the above fails for the shortcuts on the Desktop try this
alternative:
  @echo off & setlocal enableextensions
  ::
  if "%~1"=="" (
    echo Usage: "%~n0" ["The link's name on the Desktop, no path"]
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS2" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  for /f "usebackq tokens=* delims=" %%a in (
    `cscript //nologo "%vbs_%" "%~1"`) do set target_=%%a
  ::
  :: Display the result
  echo.%~1
  echo on the Desktop links to
  echo.%target_%
  ::
  :: Clean up
  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  Set WshShell = WScript.CreateObject("WScript.Shell") 'VBS2
  Set arg = WScript.Arguments 'VBS2
  strDesktop = WshShell.SpecialFolders("Desktop") 'VBS2
  Set oShellLink = WshShell.CreateShortcut(strDesktop + "\\" + arg(0)) 'VBS2
  WScript.Echo oShellLink.TargetPath 'VBS2

The output could be e.g.
  C:\_D\TEST>cmdfaq "CLIPDATE.lnk"
  CLIPDATE.lnk
  on the Desktop links to
  C:\_F\XTOOLS\CLIPDATE.CMD
If the response is empty, the link probably is not truly on your Desktop but e.g. on All Users'.

True-life usage:
  @echo off & setlocal enableextensions
  echo +------------------------------------------------------------------+
  echo ^| TSE32SCUT.CMD Run The SemWare Editor on the target of a shortcut ^|
  echo ^| By Prof. Timo Salmi, Last modified Fri 11-Sep-2009               ^|
  echo +------------------------------------------------------------------+
  echo.
  ::
  :: If it is not a shortcut
  if /i %~x1 NEQ .lnk (
    if exist "%~f1" if not exist "%~f1\" (
      start "" "C:\Program Files\TSEPro\tse32" "%~f1")
    goto :EOF)
  ::
  :: Build a Visual Basic Script
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS1" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  for /f "usebackq tokens=* delims=" %%a in (
    `cscript //nologo "%vbs_%" "%~1"`) do set target_=%%a
  ::
  :: Clean up
  for %%f in ("%vbs_%") do del %%f
  ::
  :: Run The SemWare Editor on the target file
  if "%target_%"=="" (
    echo Target not resolved
    pause
    goto :EOF)
  if not exist "%target_%" (
    echo Target "%target_%" not found
    pause
    goto :EOF)
  if exist "%target_%\" (
    echo The target "%target_%" is a folder
    pause
    goto :EOF)
  if exist "%target_%" start "" "C:\Program Files\TSEPro\tse32" "%target_%"
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '
  Set WshShell = WScript.CreateObject("WScript.Shell") 'VBS1
  Set arg = WScript.Arguments 'VBS1
  Set oShellLink = WshShell.CreateShortcut(arg(0)) 'VBS1
  WScript.Echo oShellLink.TargetPath 'VBS1

Also a pure script solution exists, but, as is so common, it does not
tolerate poison characters.
  @echo off & setlocal enableextensions
  set "target_="
  if "%~1" NEQ "" (
    if exist "%~1" (
      if /i "%~x1" equ ".lnk" (
        for /f "tokens=*" %%# in ('
          more "%~f1"^|findstr ":\\."') do (
            set "target_=%%~dpf#"))))
  if not defined target_ goto :EOF
  ::
  :: Display the result
  echo.%target_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq "C:\_L\TIMO\EXTENS03\EXCELVB.TXT.lnk"
  C:\_D\EXCEL\EXCELVB.TXT

References/Comments:
 http://msdn.microsoft.com/en-us/library/7c7x465d%28VS.85%29.aspx
 http://groups.google.com/group/alt.msdos.batch.nt/msg/add61c96f1ac8c29
 http://groups.google.fi/group/alt.msdos.batch.nt/msg/422995e930ef9d3a
 http://groups.google.fi/group/alt.msdos.batch.nt/msg/18b9dfc755e39812
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:58 2011
Subject: 178) How does one plug the modified date/time into a set of file names?
Date: Mon, 31 Jan 2011 01:02:58
From: ts@uwasa.fi (Timo Salmi)

First you may wish to revisit Item #55 and maybe also Item #12.

Consider the following set of files (the file names must not contain
exclamation marks "!")

 Directory of C:\_M

28.03.2009  15:28           112,990 Buoy.JPG
07.11.2009  09:41           170,977 Car.JPG
21.03.2009  14:09           161,703 Copy of Signpost.JPG
05.09.2009  15:28           264,249 Field.JPG
21.03.2009  14:09           161,703 Signpost.JPG
               5 File(s)        871,622 bytes

  @echo off & setlocal enableextensions enabledelayedexpansion
  rem Insert e.g. a set of *.jpg files' dates into their names
  rem
  rem Customise the source and target paths as appropriate
  set sourceDir=C:\_M
  set targetDir=C:\_M\TEMP
  ::
  if not exist "%sourceDir%\" (
    echo Exiting: Folder "%sourceDir%" not found
    goto :EOF)
  if not exist "%targetDir%\" (
    echo Exiting: Folder "%targetDir%" not found
    goto :EOF)
  ::
  rem This is essential
  pushd "%sourceDir%"
  ::
  rem The following date format is assumed DD.MM.YYYY
  rem If this does not tally with your locale's, customize fdd, fmm, fyyyy
  for /f "usebackq delims=" %%f in (`
    dir /b "%sourceDir%\*.jpg"`
    ) do (
      set fullname=%%~ff
      set basename=%%~nf
      set extensio=%%~xf
      set fdatetim=%%~tf
      set fdd=!fdatetim:~0,2!
      set fmm=!fdatetim:~3,2!
      set fyyyy=!fdatetim:~6,4!
      rem When you are sure that this is what you want, remove the security "echo"
      echo copy /-y "!fullname!" "%targetDir%\!basename!!fyyyy!!fmm!!fdd!!extensio!"
    )
  popd
  endlocal & goto :EOF

The output will be
  C:\_D\TEST>CMDFAQ
  copy /-y "C:\_M\Buoy.JPG" "C:\_M\TEMP\Buoy20090328.JPG"
  copy /-y "C:\_M\Car.JPG" "C:\_M\TEMP\Car20091107.JPG"
  copy /-y "C:\_M\Copy of Signpost.JPG" "C:\_M\TEMP\Copy of Signpost20090321.JPG"
  copy /-y "C:\_M\Field.JPG" "C:\_M\TEMP\Field20090905.JPG"
  copy /-y "C:\_M\Signpost.JPG" "C:\_M\TEMP\Signpost20090321.JPG"

If you want a locale-independent solution that is possible with a
Visual Basic Script (VBScript) aided command line script.
  @echo off & setlocal enableextensions enabledelayedexpansion
  rem Insert e.g. a set of *.jpg files' dates and times into their names
  rem
  rem Customise the source and target paths as appropriate
  set sourceDir=C:\_M
  set targetDir=C:\_M\TEMP
  ::
  if not exist "%sourceDir%\" (
    echo Exiting: Folder "%sourceDir%" not found
    goto :EOF)
  if not exist "%targetDir%\" (
    echo Exiting: Folder "%targetDir%" not found
    goto :EOF)
  ::
  rem Build a Visual Basic Script for getting a file's datestamp
  set skip=
  set vbs_=%temp%\tmp$$$.vbs
  if defined mytemp set vbs_=%mytemp%\tmp$$$.vbs
  findstr "'%skip%VBS1" "%~f0" > "%vbs_%"
  rem If you want also the times included change VBS1 to VBS in the above
  ::
  rem This is essential
  pushd "%sourceDir%"
  ::
  rem Process each file
  for /f "usebackq delims=" %%f in (`
    dir /b "%sourceDir%\*.jpg"`
    ) do (
      set fullname=%%~ff
      set basename=%%~nf
      set extensio=%%~xf
      set fdatetim=%%~tf
      for /f "usebackq delims=" %%a in (`
        cscript //nologo "%vbs_%" "!fullname!"`) do set fdatetim=%%a
      rem When you are sure that this is what you want, remove the security "echo"
      echo copy /-y "!fullname!" "%targetDir%\!basename!!fdatetim!!extensio!"
    )
  popd
  ::
  rem Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS1
  Dim arg, FDate, FileName, FSO, f 'VBS1
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS1
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS1
  Set arg = WScript.Arguments 'VBS1
  FileName = arg(0) 'VBS1
  Set f = FSO.GetFile(FileName) 'VBS1
  FDate = f.DateLastModified 'VBS1
  Wscript.StdOut.Write DatePart("yyyy",FDate) 'VBS1
  Wscript.StdOut.Write Right(0 & DatePart("m",FDate), 2) 'VBS1
  Wscript.StdOut.Write Right(0 & DatePart("d",FDate), 2) 'VBS1
  Wscript.StdOut.Write Right(0 & DatePart("h",FDate), 2) 'VBS2
  Wscript.StdOut.Write Right(0 & DatePart("n",FDate), 2) 'VBS2
  Wscript.StdOut.Write Right(0 & DatePart("s",FDate), 2) 'VBS2

  'Comment: The other alternatives for setting FDate
  'f.DateCreated f.DateLastAccessed

Naturally, the expressions could be formulated slightly differently
and more concisely such as e.g.
  Right(0 & DatePart("m",FDate), 2)
could be written as
  Right(0 & Month(FDate), 2)
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:02:59 2011
Subject: 179) How to replace an asterisk "*" in an environment variable?
Date: Mon, 31 Jan 2011 01:02:59
From: ts@uwasa.fi (Timo Salmi)

Replacing a standard character in a command-line script is straight-
forward:
  @echo off & setlocal enableextensions
  set var=This is a string
  echo %var%
  echo %var: =-%
  endlocal & goto :EOF

The output will be:
  C:\TEST>CMDFAQ
  This is a string
  This-is-a-string

However, the following will not work as one would expect
  @echo off & setlocal enableextensions
  set var=This*is*a*string
  echo %var%
  echo %var:*=_%
  endlocal & goto :EOF

Adding a backslash or some other character would work
  @echo off & setlocal enableextensions
  set var=This\*is\*a\*string
  echo %var%
  echo %var:\*=-%
  endlocal & goto :EOF

The output will be:
  C:\TEST>CMDFAQ
  This\*is\*a\*string
  This-is-a-string

A Visual Basic Script (VBScript) aided command line script solution
can be used without the complications
  @echo off & setlocal enableextensions
  set var=This*is*a*string
  echo %var%
  >"%temp%\tmp$$$.vbs" echo WScript.Echo Replace("%var%","*","-")
  for /f "delims=" %%a in ('
    cscript //nologo "%temp%\tmp$$$.vbs"') do set varNew=%%a
  for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
  echo %varNew%
  endlocal & goto :EOF

The output will be:
  C:\TEST>CMDFAQ
  This*is*a*string
  This-is-a-string

References/Comments:
 http://groups.google.com/group/alt.msdos.batch.nt/browse_frm/thread/71660980b9204c5c

--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:03:00 2011
Subject: 180) I want to exit my script if it already has been run today.
Date: Mon, 31 Jan 2011 01:03:00
From: ts@uwasa.fi (Timo Salmi)

180) I want to exit my script if it already has been run today.

Although not quite the same, this has some resemblance to avoiding
multiple calls of a script with a lockfile as explained in Item #12.

  @echo off & setlocal enableextensions
  rem The log file. Employ the current script file's name, but use .log as the extension.
  set MyLogFile="%mytemp%\%~n0.log"
  rem Get the last entry (the last line) of the log file.
  set LastLine=
  if exist "%MyLogFile%" (
    for /f "delims=" %%a in ('type "%MyLogFile%"') do set LastLine=%%a
    )
  rem Compare the last line with today's date.
  echo.%LastLine%|findstr /c:"%date%">nul
  if %errorlevel% EQU 0 (
    echo Exiting: "%~f0" has already been run today
    echo %LastLine%
    goto :EOF)
  ::
  rem Whatever your script is otherwise designed to do.
  echo Do whatever
  ::
  rem Write into the log file the time of running this script.
  echo %date% %time%>>"%MyLogFile%"
  endlocal & goto :EOF

References/Comments:
  http://groups.google.fi/group/alt.msdos.batch.nt/msg/cd55c5d253b4de50
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:03:01 2011
Subject: 181) How do I get the IP-names for a logfile containing the IP-numbers?
Date: Mon, 31 Jan 2011 01:03:01
From: ts@uwasa.fi (Timo Salmi)

Consider the following visits log file "myfile.log" (with no blank
lines)
  2010.02.01 04:33:55    24.31.147.42
  2010.02.01 04:57:06    60.251.234.1
  2010.02.01 07:13:00   38.100.41.120
  2010.02.01 08:03:16 128.107.239.233
  2010.02.01 08:05:49   77.253.23.205
  2010.02.01 08:34:51    115.113.76.5
  2010.02.01 08:49:30  203.82.252.252
  2010.02.01 09:28:12  212.88.125.245

Based on that log we wish to produce the following output
  +----------------------------------------------------+
  | IPNAMES.CMD Get the names for a list of IP numbers |
  | By Prof. Timo Salmi, last modified Mon 1-Feb-2010  |
  +----------------------------------------------------+

  "myfile.log" 8 lines
  2010.02.01 04:33:55    24.31.147.42 cpe-24-31-147-42.maine.res.rr.com
  2010.02.01 04:57:06    60.251.234.1 60-251-234-1.HINET-IP.hinet.net
  2010.02.01 07:13:00   38.100.41.120 UnKnown
  2010.02.01 08:03:16 128.107.239.233 128-107-239-233.cisco.com
  2010.02.01 08:05:49   77.253.23.205 77-253-23-205.adsl.inetia.pl
  2010.02.01 08:34:51    115.113.76.5 115.113.76.5.static-hyderabad.vsnl.net.in
  2010.02.01 08:49:30  203.82.252.252 terminus1.tsl.net.hk
  2010.02.01 09:28:12  212.88.125.245 h1df5.n2.ips.mtn.co.ug

  @echo off & setlocal enableextensions enabledelayedexpansion
  ::
  :: Define location of a temporary folder and auxiliary files
  set temp_=%temp%
  if defined mytemp set temp_=%mytemp%
  set TempFileForOneNslookupLine=%temp_%\ipnames1line.tmp
  set TempFileForOutput=%temp_%\ipnames2.tmp
  set TailOfTheOriginal=%temp_%\ipnamesTail.tmp
  ::
  :: Ensure a clean plate
  for %%f in ("%TempFileForOneNslookupLine%"
    "%TempFileForOutput%"
    "%TailOfTheOriginal%") do if exist %%f del %%f
  ::
  :: Is help required?
  set help_=
  if "%~1"=="" set help_=true
  if "%~1"=="?" set help_=true
  if "%~1"=="/?" set help_=true
  if defined help_ (call :DisplayHelp & goto :EOF)
  ::
  :: Does the original log file exist?
  set OriginalLogFile=%~1
  if not exist "%OriginalLogFile%" (
    call :ProgTitle
    >con echo.
    >con echo File "%OriginalLogFile%" not found
    goto :EOF)
  ::
  :: Count the lines in the original log file
  call :CountLines "%OriginalLogFile%" lineCount
  for /f %%n in ("%lineCount%") do set lineCount=%%n
  ::
  :: Copy the entrire original log file or optionally get its tail
  if "%~2"=="" (
    copy "%OriginalLogFile%" "%TailOfTheOriginal%" > nul
    ) else (
    call :TypeTail "%OriginalLogFile%" %lineCount% %%2 %TailOfTheOriginal%)
  ::
  :: Do the resolving line by line
  for /f "tokens=1-3" %%a in ('type "%TailOfTheOriginal%"') do (
    call :FuncRightJustify15 %%c ipnum_
    nslookup %%c|find "Name: " > "%TempFileForOneNslookupLine%"
    call :GetOneIPname "%TempFileForOneNslookupLine%" ipname_
    echo %%a %%b !ipnum_! !ipname_!>> "%TempFileForOutput%")
  ::
  :: Present the outcome
  cls
  call :ProgTitle
  >con echo.
  if "%~2"=="" echo "%OriginalLogFile%" %lineCount% lines
  if not "%~2"=="" echo "%OriginalLogFile%" last %~2 of %lineCount% lines
  type "%TempFileForOutput%"
  ::
  :: Clean up
  :_cleanup
  for %%f in ("%TempFileForOneNslookupLine%"
    "%TempFileForOutput%"
    "%TailOfTheOriginal%") do if exist %%f del %%f
  endlocal & goto :EOF

  :ProgTitle
  >con echo +----------------------------------------------------+
  >con echo ^| IPNAMES.CMD Get the names for a list of IP numbers ^|
  >con echo ^| By Prof. Timo Salmi, last modified Mon 1-Feb-2010  ^|
  >con echo +----------------------------------------------------+
  endlocal & goto :EOF

  :DisplayHelp
  call :ProgTitle
  >con echo.
  >con echo Usage: IPNAMES [InputLogFileName] [OnlyNumberOfLinesFromTheEnd]
  endlocal & goto :EOF

  :CountLines
  rem Return the number of non-blank lines of file %1
  setlocal enableextensions
    set lineCount=
    for /f %%n in ('type %1') do set /a lineCount+=1
  endlocal & set %2=%lineCount% & goto :EOF

  :TypeTail
  rem Output to file %%4 the last %3 lines of file %1 which is of length %2
  setlocal enableextensions enabledelayedexpansion
    set lineCount=
    set /a x_=%2-%3
    for /f "tokens=*" %%a in ('type %1') do (
      set /a lineCount+=1
      if !lineCount! GTR %x_% echo %%a) >> %4
    goto :EOF

  :FuncRightJustify15
  setlocal enableextensions
    set str_=               %1
    set str_=%str_:~-15%
  endlocal & set "%2=%str_%" & goto :EOF

  :GetOneIPname
  setlocal enableextensions
    set return_=UnKnown
    for /f "tokens=2" %%a in ('type %1') do set return_=%%a
  endlocal & set "%2=%return_%" & goto :EOF

You might also wish to see the WHOISME.CMD script from tscmd.zip.
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:03:02 2011
Subject: 182) How do I protect a script, e.g. for a safe access of user passwords?
Date: Mon, 31 Jan 2011 01:03:02
From: ts@uwasa.fi (Timo Salmi)

Probably the safest solution is to utilize PGP-encryption. E.g. one
could prepare with an MS-DOS PGP program the following file in a PGP-
encrypted format only. (For the details of how to encrypt a file
download the PGP program package given further down and read its
documentation.)
  @echo off
  :: Set the users and passwords information
  set user1_=foouser
  set pass1_=foopassword

To utilize that encrypted information one might have e.g. the
following plain script
  @echo off & setlocal enableextensions
  rem Note: Avoid using long filenames (a PGP old version limitation)
  ::
  :: A temporary folder
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  ::
  :: The location of the encrypted and decrypted scripts
  set EncryptedBatch=C:\_M\batch.pgp
  set DecryptedBatch=%temp_%\batch.cmd
  ::
  call :DecryptFile %EncryptedBatch% %DecryptedBatch%
  ::
  call %DecryptedBatch%
  ::
  :: Just for demonstration show that it worked
  echo user1_=%user1_%
  echo pass1_=%pass1_%
  ::
  :: Clean up
  for %%f in (%DecryptedBatch%) do if exist %%f del %%f
  for %%v in (user1_ pass1_) do set %%v=
  ::
  endlocal & goto :EOF
  ::
  :: A decryption subroutine utilizing
  :: 306805 Jan 18 1996 ftp://garbo.uwasa.fi/pc/crypt/pgp263i.zip
  :: Pretty Good Privacy RSA public key cryptography, P.Zimmermann
  :DecryptFile
  setlocal enableextensions
  set path_=%path%
  set tz_=%TZ%
  set TZ=Europe/Helsinki
  SET PGPPATH=C:\PGP
  SET PATH=%PGPPATH%;%PATH%
  %PGPPATH%\pgp -d %~1 -o %~2
  set path=%path_%
  set path_=
  set TZ=%tz_%
  endlocal & goto :EOF

The (test) output will be someting like
  C:\_M>C:\_D\TEST\CMDFAQ.CMD
  Pretty Good Privacy(tm) 2.6.3i - Public-key encryption for the masses.
  (c) 1990-96 Philip Zimmermann, Phil's Pretty Good Software. 1996-01-18
  International version - not for use in the USA. Does not use RSAREF.
  Current time: 2010/07/19 20:37 GMT

  File is encrypted. Secret key is required to read it.
  Key for user ID: John Doe <john@doe.fi>
  1024-bit key, key ID ABC1234D, created 2003/11/26

  You need a pass phrase to unlock your RSA secret key.
  Enter pass phrase: Pass phrase is good.  Just a moment......
  Plaintext filename: C:\_M\TEMP\batch.cmd
  user1_=foouser
  pass1_=foopassword

One potential true-life usage of the technique is getting or putting
material from or to an FTP site. See Item #84.

Other encryption solutions than PGP could also be used. Especially,
since the PGP encryption is not quite trivial to install on a PC the
first time. An somewhat easier method is to put the confidential
script into a scrambled zipfile.
  @echo off & setlocal enableextensions
  ::
  :: A temporary folder
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  ::
  :: The files and folders
  set EncryptedBatch=C:\_M\batch.zip
  set DecryptedBatch=batch.cmd
  set TargetFolder=%temp_%
  ::
  :: 207394 Mar 1 1999 ftp://garbo.uwasa.fi/pc/arcers/pk250dos.exe
  :: PKWARE zip un/archiver, with long filename support
  pkunzip -s "%EncryptedBatch%" "%DecryptedBatch%" "%TargetFolder%"
  ::
  :: Failure?
  if not exist "%TargetFolder%\%DecryptedBatch%" (
  echo Warning: File "%TargetFolder%\%DecryptedBatch%" not found
  echo Incorrect password for decrypting "%EncryptedBatch%"?
  goto :EOF)
  ::
  :: Call the script that was unzippped
  call "%TargetFolder%\%DecryptedBatch%"
  ::
  :: Just for demonstration show that it worked
  echo user1_=%user1_%
  echo pass1_=%pass1_%
  ::
  :: Clean up
  for %%f in ("%TargetFolder%\%DecryptedBatch%") do if exist %%f del %%f
  for %%v in (user1_ pass1_) do set %%v=
  endlocal & goto :EOF

The output
  C:\_M>C:\_D\TEST\CMDFAQ.CMD

  PKUNZIP (R) FAST! Extract Utility Version 2.50 03-01-1999
  Copr. 1989-1999 PKWARE Inc. All Rights Reserved. Shareware Version
  PKUNZIP Reg. U.S. Pat. and Tm. Off.

  Password ? **********

   Pentium II class CPU detected.
   XMS version 2.00 detected.
   DPMI version 0.90 detected.

  Searching ZIP: C:/_M/BATCH.ZIP
    Inflating: C:/_M/TEMP/BATCH.CMD
  user1_=foouser
  pass1_=foopassword

> What about running it [the sensitive script] through a batch
> compiler?

A frequent and understandable suggestion. However, no practically
useful batch compiler is known even if some nominal such programs
exist. A fact of batch programming life that has been discussed every
now and then e.g. in alt.msdos.batch.nt .
--------------------------------------------------------------------

From ts@uwasa.fi Mon Jan 31 01:03:03 2011
Subject: 183) How do I get the fileurl of a local filename?
Date: Mon, 31 Jan 2011 01:03:03
From: ts@uwasa.fi (Timo Salmi)

  @echo off & setlocal enableextensions
  ::
  :: The local target file
  set filename_=%~1
  ::
  :: Process
  for /f "tokens=*" %%f in ("%filename_%") do (
    set dr_=%%~df
    set ph_=%%~pf
    set nx_=%%~nxf)
  set "fileurl_=file:///%dr_:~0,1%^|%ph_:\=/%%nx_%"
  set "fileur2_=file:///%dr_:~0,1%|%ph_:\=/%%nx_%"
  ::
  :: Display the results
  echo %filename_%
  echo %fileurl_%
  ::
  :: Build a Visual Basic Script for lowercase
  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6
  cscript //nologo "%vbs_%" "%fileur2_%"
  ::
  :: Clean up
  for %%f in ("%vbs_%") do if exist %%f del %%f
  endlocal & goto :EOF
  '
  'The Visual Basic Script
  WScript.Echo LCase(WScript.Arguments.Unnamed(0)) 'VBS

The output could be e.g.
  C:>C:\_D\TEST\CMDFAQ.CMD C:\_G\WWW\~NETIKKA\FAQ\INFO\tscmd183.php
  C:\_G\WWW\~NETIKKA\FAQ\INFO\tscmd183.php
  file:///C|/_G/WWW/~NETIKKA/FAQ/INFO/tscmd183.php
  file:///c|/_g/www/~netikka/FAQ/info/tscmd183.php

The other way round would be
  @echo off & setlocal enableextensions
  set fileurl_=%~1
  echo %fileurl_%
  set filename_=%fileurl_:/=\%
  set filename_=%filename_:file:\\\=%
  echo %filename_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_M>C:\_D\BAS\CMDFAQ.CMD "file:///C:/_G/WWW/~NETIKKA/FAQ/INFO/TSCMD183.PHP"
  file:///C:/_G/WWW/~NETIKKA/FAQ/INFO/TSCMD183.PHP
  C:\_G\WWW\~NETIKKA\FAQ\INFO\TSCMD183.PHP
--------------------------------------------------------------------
