Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

List processing or Bouncing off the PROMPT (LONG)

2 views
Skip to first unread message

William Allen

unread,
Nov 17, 2001, 4:39:30 AM11/17/01
to
======Processing a list by "bouncing it off the PROMPT"

1) The Batch language is particularly good for producing lists

Many batch commands produce useful lists that can be redirected to a file.
For example, DIR with the /b switch (=bare list of filespecs) and XCOPY
with /l (that's the L=list only switch, available in Windows 95/98/ME GUI).

DIR C:\*.TMP /b/s/a-d>TMPLIST
xcopy C:\*.TMP C:\ /l/s/h/n/y>TMPLIST
(At the prompt, type "DIR /?" or "XCOPY /?" for brief help on the switches)
Both of these produce lists of files with extension TMP on the C: drive.
The DIR method produces an incomplete list (since DIR doesn't search within
hidden or system folders), and each item starts with the drive spec. The
XCOPY method produces a complete list and leaves off the drive spec (which
is an advantage, as we'll see below), but includes the rest of the path. With
the /n switch it gives lists in short-name alias format (=8.3 format for folder
and file names), which can also be an advantage.

2) Processing such lists

Suppose you wish to "process" such a list, for example by deleting all the
file specifications it produces? One way is to prefix each line of the list
with DEL[Space], give the list a .BAT file name, and CALL it: then this
(temporary) Batch file will carry out all the deletions (and can itself be
deleted afterwards).

To see how this prefixing might be done, consider a simple list in a file
called LIST.BAT consisting of the two items:
FileSpecOne
FileSpecTwo

If you execute this as a Batch file, not much appears to happen (unless
by some chance, "FileSpecOne" or "FileSpecTwo" happen to be valid
commands on your system).

============Screen capture
C:\WORK>list.bat

C:\WORK>FileSpecOne
Bad command or file name

C:\WORK>FileSpecTwo
Bad command or file name

C:\WORK>

C:\WORK>
============End screen capture

Each "command" just "bounces" off the prompt (_without_ being executed) and
produces a "Bad command or file name" error. However, you can capture the
resulting action in a file by executing LIST.BAT in a COMMAND /c child shell.

============Screen capture
C:\WORK>command /c list.bat>PREFIX.BAT
Bad command or file name
Bad command or file name

C:\WORK>
============End screen capture

Notice that only the "Bad command or file name" (which goes to STDERR=
standard error message device) is now seen, and the rest (which goes to
STDIN=standard input device) is redirected to PREFIX.BAT which is now:

============Screen capture (items in parentheses added as notes)
C:\WORK>type prefix.bat

C:\WORK>FileSpecOne (this is a line in PREFIX.BAT)

C:\WORK>FileSpecTwo (this is a line in PREFIX.BAT)

C:\WORK> (this is a line in PREFIX.BAT)


C:\WORK>
============End screen capture

If you change the system PROMPT to say DEL+[Space], then this happens:

============Screen capture
C:\WORK>prompt DEL (there is a [Space] after DEL)

DEL list.bat (prompt is now DEL+[Space], type LIST.BAT at prompt)

DEL FileSpecOne (now the bounce includes DEL+[Space])
Bad command or file name

DEL FileSpecTwo
Bad command or file name

DEL

DEL prompt $p$g (reset prompt to normal)

C:\WORK>
============End screen capture

The command to reset the PROMPT can be placed at the front of LIST.BAT (it
needs the @ prefix, since we don't want to ECHO the PROMPT change command
itself). If we change LIST.BAT to consist of:

============Screen capture
C:\WORK>type list.bat
@PROMPT DEL (there is a [Space] after DEL)
FileSpecOne
FileSpecTwo

C:\WORK>
============End screen capture

Then when run in a /c child shell, you get this output

============Screen capture
C:\WORK>command /c list.bat

DEL FileSpecOne
Bad command or file name

DEL FileSpecTwo
Bad command or file name

DEL


C:\WORK>
============End screen capture

and when captured in PREFIX.BAT you get this

============Screen capture
C:\WORK>command /c list.bat>PREFIX.BAT
Bad command or file name
Bad command or file name

C:\WORK>type prefix.bat

DEL FileSpecOne

DEL FileSpecTwo

DEL


C:\WORK>
============End screen capture

PREFIX.BAT has a spurious DEL line at the end. This can be removed by
adding @ECHO OFF to the end of LIST.BAT before "bouncing" it.

So if LIST.BAT consists of
@PROMPT DEL
FileSpecOne
FileSpecTwo
@ECHO OFF

then you get this:

============Screen capture
C:\WORK>command /c list.bat

DEL FileSpecOne
Bad command or file name

DEL FileSpecTwo
Bad command or file name

C:\WORK>command /c list.bat>PREFIX.BAT
Bad command or file name
Bad command or file name

C:\WORK>type prefix.bat

DEL FileSpecOne

DEL FileSpecTwo

C:\WORK>
============End screen capture

And PREFIX.BAT is the prefixed list. Putting that together into a batch
script gives this:

====Begin cut-and-paste (omit this line)
@ECHO OFF
:: Start with the PROMPT command for the required prefix
ECHO.@PROMPT DEL >LIST.BAT

:: Append the list (this is purely a demo)
ECHO.FileSpecOne>>LIST.BAT
ECHO.FileSpecTwo>>LIST.BAT

:: Append the @ECHO OFF
ECHO.@ECHO OFF>>LIST.BAT

:: Prefix the list with the PROMPT
%COMSPEC%/c LIST.BAT>PREFIX.BAT

====End cut-and-paste (omit this line)
To use the code above, cut-and-paste the text between the ==== lines
into a file with extension .BAT and base name of your choice. Lines
that don't begin with two spaces have wrapped in transmission.

And PREFIX.BAT is now a temporary Batch script that when CALLed will
process the list according to whatever temporary PROMPT you set.
That's all there is to it - except for the problems!

The problems:

===Problem 1) The "Bad command or file name" messages

There will be one of these for each line of the list to be processed. They
show that the list has "bounced" as intended, but it's convenient to remove
them. The traditional way is to use CTTY NUL (to turn off all messages,
and, NOTE THIS, keyboard input as well) and CTTY CON to turn them back on
again. Because CTTY NUL turns off keyboard input, you need to make sure the
CTTY CON turns it on again before the script ends:

====Begin cut-and-paste (omit this line)
@ECHO OFF
:: Start with the PROMPT command for the required prefix
ECHO.@PROMPT DEL >LIST.BAT

:: Append the list (this is purely a demo)
ECHO.FileSpecOne>>LIST.BAT
ECHO.FileSpecTwo>>LIST.BAT

:: Append the @ECHO OFF
ECHO.@ECHO OFF>>LIST.BAT

:: Prefix the list with the PROMPT
CTTY NUL
%COMSPEC%/c LIST.BAT>PREFIX.BAT
CTTY CON

====End cut-and-paste (omit this line)
To use the code above, cut-and-paste the text between the ==== lines
into a file with extension .BAT and base name of your choice. Lines
that don't begin with two spaces have wrapped in transmission.

This method produces a spurious blank line in the display as the CTTY
commands are executed. You can back up one line and hide this if ANSI.SYS
is loaded. However, a useful alternative method (that doesn't need ANSI.SYS)
is to put the prefixing code line in a Subroutine, and call it in a NUL/c shell:

====Begin cut-and-paste (omit this line)
@ECHO OFF
IF (GOTO:)==(%1) %1%2 (Subroutine handler)

:: Start with the PROMPT command for the required prefix
ECHO.@PROMPT DEL >LIST.BAT

:: Append the list (this is purely a demo)
ECHO.FileSpecOne>>LIST.BAT
ECHO.FileSpecTwo>>LIST.BAT

:: Append the @ECHO OFF
ECHO.@ECHO OFF>>LIST.BAT

:: Call the Prefix subroutine in a NUL/c shell to suppress messages
%COMSPEC% NUL/c %0 GOTO: _PREFIX

GOTO EOF (=Subroutine code follows=)
:_PREFIX
%COMSPEC%/c LIST.BAT>PREFIX.BAT

:EOF (End-of-file)

====End cut-and-paste (omit this line)
To use the code above, cut-and-paste the text between the ==== lines
into a file with extension .BAT and base name of your choice. Lines
that don't begin with two spaces have wrapped in transmission.

In practice, the files PREFIX.BAT and LIST.BAT could be created in your TEMP
folder to avoid the need to write clutter to the current folder. And, of course, you
would include a line to CALL PREFIX.BAT to do the job of processing the list.
And commands to delete both LIST.BAT and PREFIX.BAT as the script ends.

===Problem 2) One of the items is a command in the PATH

The key principle of the PROMPT bounce method is that each line should
_bounce_ as a bad command, and not _execute_ as a good one. But suppose
one or more of the lines happens to be a valid command in the system
PATH? Then they won't bounce, they'll be executed, and create havoc.

The usual workaround for this is to (temporarily) save the system PATH,
clear it, and then do the bounce, then restore the PATH. This way, no
commands in the PATH will be found during the bounce operation.

===Problem 3) One of the items is a command in the current folder

Of course, if one of the list items is a valid command in the current
folder, clearing the PATH won't help stop its being executed. So it
still won't bounce correctly.

The usual workaround for this is to (temporarily) create an empty folder,
make that folder current, do the bounce (in the empty folder), then
return to current folder afterwards.

For a demo using both Problem 2 and 3 workarounds, see Note 1.

===Problem 4) One of the items is an internal command

Suppose LIST.BAT consists of:
@PROMPT DEL
FileSpecOne
FileSpecTwo
pause
@ECHO OFF

When you try to bounce it off the PROMPT (which will look like DEL ) the
"pause" won't bounce, it will be executed and stall the process like this:

============Screen capture
C:\WORK>command /c list.bat

DEL FileSpecOne
Bad command or file name

DEL FileSpecTwo
Bad command or file name

DEL pause
Press any key to continue . . .
============End screen capture

The workaround is to make sure this doesn't happen, by configuring the list
to avoid the possibility. Often, you will know the list won't contain such
items. For other occasions, you need to use ingenuity in constructing the
list. See problem 5 for more details on the workarounds.

===Problem 5) Some items are fully-qualified executable filespecs

With DIR /b /s listings of executables, the list will consist of full file
specifications. So neither clearing the path, nor working in an empty
folder will help. For example, if (with Windows 95/98/ME) LIST.BAT
consists of:
@PROMPT DEL
FileSpecOne
FileSpecTwo
C:\WINDOWS\COMMAND\choice.com
@ECHO OFF

then the choice.com line won't bounce properly, it will stall:

============Screen capture
C:\WORK>command /c list.bat

DEL FileSpecOne
Bad command or file name

DEL FileSpecTwo
Bad command or file name

DEL C:\WINDOWS\COMMAND\choice.com
[Y,N]?
============End screen capture

The workaround for both problems 4 and 5 is to prevent the problem
happening in the first place. Two methods I've published before:

(a) SUBST a spare drive letter.
For DIR lists, you can temporarily SUBST an unused drive letter, say P, to
produce the list (then all the drive specs will be P:\) and then cancel the
substitution for the bounce, then restore it while processing the list. I
published a working demo of this technique recently (see Note 2 below).
This technique avoids all the problems 2, 3, 4, and 5.

(b) Use XCOPY /L listings
XCOPY /L (=list only) listings are more PROMPT-bounce "friendly" in that
they can often be configured to avoid all the problems 2, 3, 4, and 5
without needing any of the workarounds at all. I've published several
recent examples of this. For the most flexible technique I've discovered
so far, see Note 3 below.

===Problem 6) Some items contain % characters

When the list items contain % characters, the PROMPT-bounce processing will
attempt to interpret them in the normal Batch way: single % characters may
be lost, pairs of %'s will be reduced to single % characters, and text
delimited by % characters may be interpreted as environment variables.
This will corrupt the item in the resulting processed list.

Workarounds for this include using SED to amend the list, or do the
prefixing entirely (see note 4); or using the Microsoft CSCRIPT batch
interface to amend the list or do the prefixing entirely (see Note 5).
Either of these will avoid the usual % interpretation (CSCRIPT can
have % interpretation turned ON and OFF as you please).

--
William Allen

Note 1
Demo of PATH cancel and empty folder working for PROMPT-bounce
From: "William Allen"
Newsgroups: alt.msdos.batch
Subject: Re: batch file to search drives
Date: Fri, 16 Nov 2001 06:54:54 -0000
Message-ID: <9t2d9c$16kc4c$2...@ID-55970.news.dfncis.de>

Note 2
Working demo of SUBST technique for PROMPT-bounce prefixing:
From: "William Allen"
Newsgroups: alt.msdos.batch
Subject: Re: attrib - wildcards with folders
Date: Sat, 10 Nov 2001 19:15:16 -0000
Message-ID: <9sjubl$12g90v$2...@ID-55970.news.dfncis.de>

Note 3:
Running FOR IN DO on all subfolders of a particular folder with XCOPY /L
cyclic error suppression:
From: "William Allen"
Newsgroups: alt.msdos.batch
Subject: FOR IN DO loop executed in all subfolders
Date: Fri, 16 Nov 2001 21:15:08 -0000
Message-ID: <9t3vsf$93vo$1...@ID-55970.news.dfncis.de>

You can read old Usenet posts at:
http://groups.google.com/advanced_group_search

Note: Google search by Message-ID is usually the quickest.
The Message-ID is the identifier in the <angle> brackets.
Simply cut-and-paste the Message-ID into Google page above.

Note 4:
Windows compatible version of SED (the Stream EDitor) freeware from:
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/sed302b.zip
ftp://ftp.cdrom.com/.27/simtelnet/gnu/djgpp/v2gnu/sed302b.zip
source-code-inclusive version
ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/sed302s.zip
ftp://ftp.cdrom.com/.27/simtelnet/gnu/djgpp/v2gnu/sed302s.zip

Note 5:
CSCRIPT.EXE is a first-party (Microsoft) Batch file interface for
Windows 95/98/ME, installed with WSH (Windows Script Host):

Windows Script Host main page for information:
http://msdn.microsoft.com/scripting/


Outsider

unread,
Nov 17, 2001, 5:03:36 AM11/17/01
to
William Allen wrote:
>
> ======Processing a list by "bouncing it off the PROMPT"
>
> 1) The Batch language is particularly good for producing lists

Which batch language would that be? Is that DOS batch or
William Allen batch?

--
<!-Outsider//->
MS-DOS 6.22, Windows for Workgroups 3.11, Netscape Communicator 4.08

William Allen

unread,
Nov 18, 2001, 1:33:00 AM11/18/01
to
William Allen wrote in message
...snip

> Then when run in a /c child shell, you get this output
>
> ============Screen capture
> C:\WORK>command /c list.bat
>
> DEL FileSpecOne
> Bad command or file name
>
> DEL FileSpecTwo
> Bad command or file name
>
> DEL
>
>
> C:\WORK>
> ============End screen capture

I should have mentioned that, because the LIST.BAT script
is run in a child shell, the PROMPT change it makes is lost
again when the script ends and the child shell closes. That's
why there is no need to restore the prompt again when using
this prefix method. Your original prompt returns automatically,
as shown above.

--
William Allen


0 new messages