Both of these utilities mostly work as intended. However, there is some
kind of problem that frequently results in printing a generally garbled
version of the message "The system cannot find the file". The message is
garbled in such a way as to strongly suggest that memory is somehow being
trashed.
These errors seem to usually (always?) result from using the FOR command
with the /F option to process contant text that has been enclosed in single
quotes, when the FOR command is NOT even being used to work with files. The
errors seem to occur *after* the FOR command has finished processing and is
terminating or cleaning up after itself.
I would appreciate if someone else could test these scripts to see if they
are able to duplicate the same errors that I see, and also to let me know if
you see anything that I am doing wrong. The content of my two scripts is
provided below, along with a simple test script that frequently produces the
error message. The test script runs in a continuous loop and must be
terminated using Ctrl-C when you are ready to quit.
temp.bat:
@echo off
rem Put this in the same folder as the other two files,
rem and run it from a command promp to test them.
rem Theoretically you should see three lines containing
rem "this is a test", followed by three lines with "is",
rem but you will probably also see some garbled
rem "The system cannot find the file" messages.
rem Hit Ctrl-c to exit when you have seen enough.
:start
echo "this is a test"|cmd /c dequote
call dequote /t "this is a test"
call dequote echo "this is a test"
echo.
echo this is a test|cmd /c scan 2
call scan 2 /t this is a test
call scan 2 echo this is a test
echo.
goto start
dequote.bat:
@echo off
:init
if '%1' equ '/?' goto help
if '%1' equ '-?' goto help
if /I '%1' equ '/h' goto help
if /I '%1' equ '-h' goto help
:main
if '%1' equ '' (
rem deQuote as a filter, could return multiple lines
rem for /f "tokens=* usebackq" %%s in (`NullFilter`) do echo %%~s
for /f "tokens=* usebackq" %%s in (`find /v "xyzzyx963852741"`) do echo %%~s
) else (
if /I '%1' equ '/t' (
rem deQuote text from command line, always a single line
for /f "tokens=1,* usebackq" %%a in ('%*') do echo %%~b
) else (
rem deQuote output from specified command, could return multiple lines
for /f "tokens=* usebackq" %%o in (`%*`) do echo %%~o
)
)
goto end
:help
echo deQuote.bat
echo Copyright (c) 2009-09-11 by Kevin A. Myers
echo All rights reserved.
echo.
echo Removes enclosing quotes from source text.
echo.
echo Syntax:
echo deQuote
echo deQuote /t <text>
echo deQuote <command>
echo.
:end
scan.bat:
@echo off
:init
if '%1' equ '/?' goto help
if '%1' equ '-?' goto help
if /I '%1' equ '/h' goto help
if /I '%1' equ '-h' goto help
:main
setlocal
if '%1' equ '' (set token=1) else (set token=%~1)
if '%delims%' neq '' set delims=delims=%delims%
if '%2' equ '' (
rem scan as a filter
rem for /f "tokens=%token% usebackq %delims%" %%s in (`NullFilter`) do echo
%%s
for /f "tokens=%token% usebackq %delims%" %%s in (`find /v
"xyzzyx963852741"`) do echo %%s
) else (
if /I '%2' equ '/t' (
rem scan text from command line
for /f "tokens=2,* usebackq" %%a in ('%*') do (
for /f "tokens=%token% usebackq %delims%" %%t in ('%%b') do echo %%t
)
) else (
rem scan output from specified command
for /f "tokens=1,* usebackq" %%a in ('%*') do (
for /f "tokens=%token% usebackq %delims%" %%o in (`%%b`) do echo %%o
)
)
)
endlocal
goto end
:help
echo scan.bat
echo Copyright (c) 2009-09-11 by Kevin A. Myers
echo All rights reserved.
echo.
echo Extract token(s) from specified input line(s).
echo Delimiters are taken from a delims environment variable.
echo.
echo Syntax:
echo scan
echo scan <token>
echo scan <token> /t <text>
echo scan <token> <command>
echo.
:end
--
Kevin A. Myers
Myers Engineering
Round Rock, Texas
Since this is far from a trivial set of batch files, you should ask
the batch file experts in alt.msdos.batch.nt for advice. They love
this type of challenge!
Actually, if you look a little closer you will find those batch files
are really quite simple. They both essentially boil down to executing
some FOR commands that look similar to this:
for /f "tokens=4 usebackq" %%a in ('a b c d e f g h') do echo %%a
According to the docs, that command should produce the command "echo
d", which should in turn echo the d character to the screen.
In fact that does happen. However, quite often, under some
circumstances that I'm not completely sure of, it also produces a
garbled error message *after* the echo command.
The error message is usually "The system cannot find the file "
followed by some graphics characters, but sometimes it is more messed
up than that.
Sometimes I get this error after executing a command similar to the
above only once, other times it takes more tries.
It appears to be affected but not eliminated by use of "set local
enabledelayedexpansion".
Here is a simple test that you can try.
I have tested this on two different machines, both running Windows XP
Service Pack 3 with all critical updates installed.
The results includes garbled error messages on both machines.
Copy the following into a batch file on your machine, then run the
batch file from a command prompt.
@echo off
for /f "tokens=4 usebackq" %%a in ('a b c d e f g h') do echo %%a
for /f "tokens=4 usebackq" %%b in ('a b c d e f g h') do echo %%b
for /f "tokens=4 usebackq" %%c in ('a b c d e f g h') do echo %%c
for /f "tokens=4 usebackq" %%d in ('a b c d e f g h') do echo %%d
for /f "tokens=4 usebackq" %%e in ('a b c d e f g h') do echo %%e
for /f "tokens=4 usebackq" %%f in ('a b c d e f g h') do echo %%f
for /f "tokens=4 usebackq" %%g in ('a b c d e f g h') do echo %%g
for /f "tokens=4 usebackq" %%h in ('a b c d e f g h') do echo %%h
for /f "tokens=4 usebackq" %%i in ('a b c d e f g h') do echo %%i
for /f "tokens=4 usebackq" %%j in ('a b c d e f g h') do echo %%j
for /f "tokens=4 usebackq" %%k in ('a b c d e f g h') do echo %%k
for /f "tokens=4 usebackq" %%l in ('a b c d e f g h') do echo %%l
for /f "tokens=4 usebackq" %%m in ('a b c d e f g h') do echo %%m
for /f "tokens=4 usebackq" %%n in ('a b c d e f g h') do echo %%n
for /f "tokens=4 usebackq" %%o in ('a b c d e f g h') do echo %%o
for /f "tokens=4 usebackq" %%p in ('a b c d e f g h') do echo %%p