How to pass a character like " " to a function

  • This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
Apr 11, 2009
7
0
#1
First, I'm not a programmer, so go easy on me! I'm using TCMD v11.00.48 x64.

I've been struggling to figure out how to get a space character passed from the command line to @replace in a batch file. @replace works fine when it's written like %@replace[ ,_,text]. But it won't work if I pass " " from the command line and then use @unquote, such as %@replace[%@unquote[%1],%2,%3]. For example, what happens is:

SET 1=" "
SET x=@unquote[%1]
ECHO %x

In this case X seems to have null value. I also tried to directly send the character to a variable, as in:

SET 1=%@char[32]
%@replace[%1,%2,%3].

But %@char[32] seems to return a null value. I have worked around it by testing for " " and making a special version of @replace for that situation, but I can't help but feel that there must be a more elegant way to handle " " on the command line. What follows is what I've written so far (and it does work!). Thanks!

:: FCLEAN.BTM
:: Renames files by replacing *ALL* instances of [Search String] with [Replacement String] in file names matching [Filespec].
:: John A. Long

@echo off
SETLOCAL
UNSET *
SET X=0

echo.

SET fn=%@findfirst[%1,-d]
DO until "%fn" == ""
IFF "%1" == "/?" .OR. "%1" == "" THEN
(GOTO PARAMETERS)
ELSEIFF "%2" == "/T" .OR. "%2" == "" THEN
(echo %fn & set fn=%@findnext[%1,-d] & ITERATE)
ELSEIFF %2 == " " .AND. %3 != " " THEN
SET newfn=%@replace[ ,%3,%fn]
ELSEIFF %2 != " " .AND. %3 == " " THEN
SET newfn=%@replace[%2, ,%fn]
ELSEIFF %2 == " " .AND. %3 == " " THEN
SET newfn=%@replace[ , ,%fn]

ELSE
SET newfn=%@replace[%2,%3,%fn]
ENDIFF

IF %fn != %newfn .AND. %2 != "/t" (ren "%fn" "%newfn" & SET X=%@eval[%x + 1])
echo.
set fn=%@findnext[%1,-d]
ENDDO

Echo.
Echo %X files processed.
GOTO END

:PARAMETERS
echo.
echo FCLEAN.BTM
echo Renames files by replacing *ALL* instances of [Search String] with [Replacement String] in file names matching [Filespec].
echo.
echo USAGE
echo =====
echo Display parameters: fclean /?
echo Test Filespec on filenames: fclean [Filespec] [/T]
echo Replace Search String with Replacement String: fclean [Filespec] [Search String] [Replacement String]
echo.
echo NOTE: [Filespec] may contain wild cards. Use " " to denote a SPACE.
echo Special characters such as ^,&,(,( must be proceeded by a "^", as in ^&.
echo Use with caution.
echo.
echo EXAMPLE
echo =======
echo The command FCLEAN.BTM zz* " " _
echo will replace all spaces with underscores in files beginning with zz.
echo.
echo The command FCLEAN.BTM *.txt .txt .cmd
echo will replace file extension .txt with extension .cmd in all files with the extension .txt.
echo.

:END
ENDLOCAL
 
#3
How to pass a character like " " to a function as a command line argument

| First, I'm not a programmer, so go easy on me! I'm using TCMD
| v11.00.48 x64.
|
| I've been struggling to figure out how to get a space character passed
| from the command line to @replace in a batch file. @replace works fine
| when it's written like %@replace[ ,_,text]. But it won't work if I
| pass " " from the command line and then use @unquote, such as
| %@replace[%@unquote[%1],%2,%3]. For example, what happens is:
|
| SET 1=" "
| SET x=@unquote[%1]
| ECHO %x
|
| In this case X seems to have null value. I also tried to directly send
| the character to a variable, as in:
|
| SET 1=%@char[32]
| %@replace[%1,%2,%3].
|
| But %@char[32] seems to return a null value. I have worked around it
| by testing for " " and making a special version of @replace for that
| situation, but I can't help but feel that there must be a more elegant
| way to handle " " on the command line. What follows is what I've
| written so far (and it does work!). Thanks!

The issue is not with %@char[32] but with SET. As is documented
in HELP topic "set.htm" SET drops trailing whitespace in the value it
assigns to the variable, UNLESS it is protected from evaluation by
the parser. In all versions of the JPsoft command processors (going
back to 4DOS) you protect strings with back quotes `. All of the
commands below would work for you:

set l=` `
set l= ``
set l=%@char[32]``
set l=`%@char[32]`

The first three set the variable to a single space character; the
last sets the variable to the string %@char[32] which will be
converted to a space character each time the parser encounters %l in
a command. For purposes of understandability, I would recommand
either of the first two methods.
There are many simplifications one can make to your batch file,
not the least of which is the use of the TEXT and QUIT commands, as
shown below. Of course, this comes from one who is a retired
professional programmer with over 15 years specific experience with
JPsoft command processors.

There are some errors in the program.

1/ @REPLACE is case sensitive. Windows is case retentive. A file
associated with extension .txt may actually have any one of the
following eight extensions: .txt .txT .tXt .tXT .Txt .TxT .TXt .TXT.
Vince Fatica provided the freeware plugin function @XREPLACE to
overcome this limitation. Either one works on STRINGS. Consequently
your second example will replace the extension .txtfile with
.cmdfile, and rename x.txt.csv to x.cmd.csv.

2/ Every use of @FINDFIRST allocates internal memory. It must be
followed by @FINDCLOSE to release that memory, else TCC will
eventually crash. OTOH you can use either FOR or DO to iterate through
all file specifications matching the desired wildcard without
explicit opening and closing the directory search functions.

Major simplifications are based on the following:

1/ It is generally much faster to parse the command line as much as
possible before the loop rather then to repeat the parsing every time.
Of course, there are cases when this cannot be done.

2/ IFF is designed so that you would not need to use command groups
to execute multiple commands once you found condition which is TRUE.
Just list each command in a separate line, resulting in much more
readable code.

:: FCLEAN.BTM
:: Renames files by replacing *ALL* instances of [Search String] with
:: [Replacement String] in file names matching [Filespec].
:: John A. Long

======================================
W A R N I N G ! N O T T E S T E D !

======================================
--- begin code ---
@echo off

if %# LT 1 .or. %@ GT 3 .or. %1 == /? goto USAGE

SETLOCAL

switch %#
case 1
goto LIST
case 2
if %2 EQ /T goto LIST
goto USAGE
case 3
iff %2 EQC %3 then
echo Cannot change string %2 to itself
quit
endiff
switch %2
case " "
set src= ``
default
set src=%2
endswitch
switch %3
case " "
set tgt= ``
default
set tgt=%3
endswitch
endswitch

SET X=0
echo.

do fn in /a:-d %1
set x=%@inc[%x]
ren %@quote[%fn] %@quote[%@replace[%src,%tgt,%fn]]
enddo
Echo %X files renamed.
QUIT

:LIST
SET X=0
echo.
do fn in /a:-d %1
set x=%@inc[%x]
echo %fn
enddo
Echo %X files would be renamed.
QUIT

:USAGE
text

FCLEAN.BTM

Renames files by replacing *ALL* instances of [Search String] with
[Replacement String] in file names matching [Filespec].

USAGE
====Display usage:

fclean /?

List matching files:

fclean Filespec [/T]

Replace Search_String with Replacement_String:

fclean Filespec Search_String Replacement_String

NOTES:
Filespec may contain wild cards.

Use " " to denote a SPACE string.

In strings special characters such as ^,&,(,( must be proceeded by
the EscapeChar (default: caret "^"), e.g. ^&.

USE WITH CAUTION.

EXAMPLE
======The command
FCLEAN.BTM zz* " " _
will replace all spaces with underscores in files beginning with zz.

The command
FCLEAN.BTM *.txt .txt .cmd
will replace .txt with .cmd in all filenames including .txt.

endtext
--- end of code ---


--
HTH, Steve
 
Apr 11, 2009
7
0
#4
re: How to pass a character like " " to a function

Steve, there's a lot of good learning for me in the example you've given. I'm going to go over it closely today.

Thanks so much to both of you!