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

No file VBS hybrid scripting

1,067 views
Skip to first unread message

Tom Lavedas

unread,
Dec 6, 2012, 10:48:34 AM12/6/12
to
Maybe a year ago, I was involved in a thread regarding using VBScript code to augment batch processing. One of the prime attribute being sought was a way to do that without requiring an external temporary script file. Several good solutions were developed and posted (sorry, I did not take the time to look up the thread). However, the results were a bit convoluted, IMHO (even the ones I offered).

I recently revisited the subject for no particular reason. The intervening year seems to have provided a new perspective, resulting in a one liner that can even beinstalled as a DOSKEY macro, if you wanted. It makes use of command line programming of mshta.exe to host the VBScript code. The doskey macro looks like this (all one line) ...

vb=for /f "delims=" %a in ('mshta vbscript:Execute("createobject(""scripting.filesystemobject"").GetStandardStream(1).writeline($*)"
^^^&close^)') do @echo.%a

It is probably best loaded via the /MACROS:filespec DOSKEY argument, since it is rather involved.

The batch file code could be as simple as this (again one line) ...

@for /f "delims=" %a in ('mshta vbscript:Execute("createobject(""scripting.filesystemobject"").GetStandardStream(1).writeline(%*)"
^^^&close^)') do @echo.%a

But for better presentation and easier maintenance, I would propose this ...

:: VBS.cmd, Tom Lavedas 12/0620012
@echo off & setlocal
set VBS=vbscript:Execute("createobject(""scripting.filesystemobject"")
set VBS=%VBS%.GetStandardStream(1).writeline
for /f "delims=" %%a in ('mshta %VBS%(%*)"^^^&close^)') do echo.%%a
::
:: Examples
::
:: Display ASCII equivalents (in hex) for first 127 characters ...
:: @for /l %N in (1,1,127) do @vbs right(""00""+hex(""%N"")+"":"",4)+chr(%N)
::
:: @for /f %Y in ('vbs date-1') do set Yesterday=%Y
::
:: @for /f %P in ('vbs 4*atn(1^)') do echo PI = %P
::
:: @for /f %S in ('vbs sqr(2^)') do echo Sq Root of2 = %S

I added internal comments of some command line examples. Of course, double up the percent signs to use them in another calling batch. Note the need for double quoting of VBS string arguments and the escaping of closing parentheses in the FOR's set argument. Other than that, the use is pretty straight forward and spaces in the argument string are acceptable.

This approach is a bit slower that others, especially the first time it is used, and can only handle expressions that are written in a single line of code.

I tested only with IE8 in Win7, so I welcome comments about compatibility with other OS/IE combinations.
__________________________
Tom Lavedas

foxidrive

unread,
Dec 6, 2012, 11:08:49 AM12/6/12
to
On 7/12/2012 2:48 AM, Tom Lavedas wrote:

> But for better presentation and easier maintenance, I would propose this ...
>
> :: VBS.cmd, Tom Lavedas 12/0620012
> @echo off & setlocal
> set VBS=vbscript:Execute("createobject(""scripting.filesystemobject"")
> set VBS=%VBS%.GetStandardStream(1).writeline
> for /f "delims=" %%a in ('mshta %VBS%(%*)"^^^&close^)') do echo.%%a
> ::
> :: Examples
> ::
> :: Display ASCII equivalents (in hex) for first 127 characters ...
> :: @for /l %N in (1,1,127) do @vbs right(""00""+hex(""%N"")+"":"",4)+chr(%N)
> ::
> :: @for /f %Y in ('vbs date-1') do set Yesterday=%Y
> ::
> :: @for /f %P in ('vbs 4*atn(1^)') do echo PI = %P
> ::
> :: @for /f %S in ('vbs sqr(2^)') do echo Sq Root of2 = %S
>
>
> I tested only with IE8 in Win7, so I welcome comments about compatibility with other OS/IE combinations.

It works fine in Win8 too Tom. That's some trickery...

The ascii display doesn't play well with some control characters in Win8 - better to start at 32/33 mebbe?




--
foxi

ten.n...@virgin.net

unread,
Dec 6, 2012, 1:09:04 PM12/6/12
to
On Thu, 06 Dec 2012 15:48:34 -0000, Tom Lavedas <tglb...@verizon.net>
wrote:

> :: VBS.cmd, Tom Lavedas 12/0620012
> @echo off & setlocal
> set VBS=vbscript:Execute("createobject(""scripting.filesystemobject"")
> set VBS=%VBS%.GetStandardStream(1).writeline
> for /f "delims=" %%a in ('mshta %VBS%(%*)"^^^&close^)') do echo.%%a
> ::
> :: Examples
> ::
> :: Display ASCII equivalents (in hex) for first 127 characters ...
> :: @for /l %N in (1,1,127) do @vbs
> right(""00""+hex(""%N"")+"":"",4)+chr(%N)
> ::
> :: @for /f %Y in ('vbs date-1') do set Yesterday=%Y
> ::
> :: @for /f %P in ('vbs 4*atn(1^)') do echo PI = %P
> ::
> :: @for /f %S in ('vbs sqr(2^)') do echo Sq Root of2 = %S
>
> <snip />
>I tested only with IE8 in Win7, so I welcome comments about
> compatibility with other OS/IE combinations.
>

No problems here Windows 7 x64 using IE10 beta.

foxidrive

unread,
Dec 6, 2012, 1:14:09 PM12/6/12
to
On 7/12/2012 2:48 AM, Tom Lavedas wrote:

> I tested only with IE8 in Win7, so I welcome comments about compatibility with other OS/IE combinations.

It works fine in Win8 too Tom. That's some trickery...

I forgot to add, this Win8 uses IE 10.

I wasn't really on top of the fact that it uses bits of IE ...


--
foxi

Auric__

unread,
Dec 6, 2012, 2:28:54 PM12/6/12
to
Tom Lavedas wrote:

> Maybe a year ago, I was involved in a thread regarding using VBScript
> code to augment batch processing. One of the prime attribute being
> sought was a way to do that without requiring an external temporary
> script file. Several good solutions were developed and posted (sorry, I
> did not take the time to look up the thread). However, the results were
> a bit convoluted, IMHO (even the ones I offered).
>
> I recently revisited the subject for no particular reason. The
> intervening year seems to have provided a new perspective, resulting in
> a one liner that can even beinstalled as a DOSKEY macro, if you wanted.
> It makes use of command line programming of mshta.exe to host the
> VBScript code. The doskey macro looks like this (all one line) ...
>
> vb=for /f "delims=" %a in ('mshta
> vbscript:Execute("createobject(""scripting.filesystemobject"").GetStandar
> dStream(1).writeline($*)"^^^&close^)') do @echo.%a

32-bit XP SP3 MSIE 8

Perhaps I'm copying wrong somehow; not really sure. Here's how it got
entered and the results:

C:\users\auric\Desktop>doskey vb=for /f "delims=" %a in ('mshta vbscript:
Execute("createobject(""scripting.filesystemobject"").GetStandardStream(1
).writeline($*)"^^^&close^)') do @echo.%a

C:\users\auric\Desktop>vb
') was unexpected at this time.

Putting it in a macrofile works, though:

C:\users\auric\Desktop>doskey /macrofile=vb.tmp

C:\users\auric\Desktop>vb 4*atn(1)
3.14159265358979

> It is probably best loaded via the /MACROS:filespec DOSKEY argument,
> since it is rather involved.
>
> The batch file code could be as simple as this (again one line) ...
>
> @for /f "delims=" %a in ('mshta
> vbscript:Execute("createobject(""scripting.filesystemobject"").GetStandar
> dStream(1).writeline(%*)" ^^^&close^)') do @echo.%a
>
> But for better presentation and easier maintenance, I would propose this

[snip]

> I added internal comments of some command line examples. Of course,
> double up the percent signs to use them in another calling batch. Note
> the need for double quoting of VBS string arguments and the escaping of
> closing parentheses in the FOR's set argument. Other than that, the use
> is pretty straight forward and spaces in the argument string are
> acceptable.
>
> This approach is a bit slower that others, especially the first time it
> is used, and can only handle expressions that are written in a single
> line of code.
>
> I tested only with IE8 in Win7, so I welcome comments about
> compatibility with other OS/IE combinations.

Same system as above (XPSP3 MSIE8), works good.

Didn't test on my XP64 system but I'm guessing it'll be about the same.

--
One who cannot cast away a treasure at need is in fetters.

Tom Lavedas

unread,
Dec 6, 2012, 2:56:35 PM12/6/12
to
On Thursday, December 6, 2012 2:28:54 PM UTC-5, Auric__ wrote:
> Tom Lavedas wrote:

Try this from the command prompt to define the macro:

doskey vb=for /f "delims=" %a in ('mshta vbscript:Execute("createobject("""scripting.filesystemobject""").GetStandardStream(1).writeline($*)"^^^^^^^&close^^^)') do @echo.%a

I kinda knew it was trickier from the keyboard, but glossed over it in my first post. The command line definition needs many more escape characters and extra double quotes to get the right number into the macro.
____________________________
Tom Lavedas

Auric__

unread,
Dec 6, 2012, 8:23:23 PM12/6/12
to
Tom Lavedas wrote:

> Try this from the command prompt to define the macro:
>
> doskey vb=for /f "delims=" %a in ('mshta
> vbscript:Execute("createobject("""scripting.filesystemobject""").GetStand
> ardStream(1).writeline($*)"^^^^^^^&close^^^)') do @echo.%a

Jesus christ!

> I kinda knew it was trickier from the keyboard, but glossed over it in
> my first post. The command line definition needs many more escape
> characters and extra double quotes to get the right number into the
> macro.

Ok, it works. Looks a bit like line noise, though. Makes me feel like I need
to turn off local echo.

I just tested on Win2k w/ MSIE 5.5 (yay vmware); doesn't work there at all,
in any form. Doskey reports "invalid macro definition" regardless of which
version I try, and the batch file (and entering it at the command line) gives
me "Internet Explorer cannot open the Internet site vbscript:Execute([etc]).
No such interface supported." So it looks like there's a minimum MSIE version
needed; my guess is either 7 or 8 (but I don't have 6 or 7 installed anywhere
to test).

--
- Do you ever tire of being right?
- It's been less of a treat lately, I'll admit.

Timo Salmi

unread,
Dec 7, 2012, 2:07:33 AM12/7/12
to
An esoteric curiosity. Exactly what fits here well.

All the best, Timo

--
Prof. (emer.) Timo Salmi, Vaasa, Finland
http://www.netikka.net/tsneti/homepage.php
Useful CMD script tricks http://www.netikka.net/tsneti/info/tscmd.php

Tom Lavedas

unread,
Dec 7, 2012, 8:51:36 AM12/7/12
to
On Thursday, December 6, 2012 8:23:23 PM UTC-5, Auric__ wrote:
> Tom Lavedas wrote:
>
> Ok, it works. Looks a bit like line noise, though.

Yes, and when I looked at it again, I am confused as to why it worked at all. Upon further consideration I suspect (but have not proven) it is causing a runtime error which causes the HTA window to close because the process aborts - but not until after it has output the expected result.

Regardless of whether this is the correct interpretation, I have altered the construct, which makes it a tiny bit less like 'line noise' ...

Command prompt entry to create macro:

doskey vb=for /f "delims=" %a in ('mshta vbscript:Execute("createobject("""scripting.filesystemobject""").GetStandardStream(1).write($*):close"^^^)') do @echo %a

The macro file version for DOSKEY:

vb=for /f "delims=" %a in ('mshta vbscript:Execute("createobject(""scripting.filesystemobject"").GetStandardStream(1).write($*):close"^)') do @echo %a

And finally the batch file version:

:: VBS.cmd, Tom Lavedas 12/07/2012
@echo off & setlocal
set VBS=vbscript:Execute("createobject(""scripting.filesystemobject"")
set VBS=%VBS%.GetStandardStream(1).write
for /f "delims=" %%a in ('mshta %VBS%(%*):close"^)') do echo.%%a
:: Examples
::
:: Display ASCII equivalents (in hex) for first 127 characters ...
:: @for /l %N in (1,1,127) do @vbs right(""00""+hex(""%N"")+"":"",4)+chr(%N)
::
:: @for /f %Y in ('vbs date-1') do set Yesterday=%Y
::
:: @for /f %P in ('vbs 4*atn(1^)') do set PI = %P
::
:: This form just displays the results
:: vbs SQR(2^)

Finally, regarding the applicability of this approach: I suspect the command line support for the "vbscript:" construct is version dependent. I seem to remember people lamenting the fact that it was possible to use "javascript:" on the command line, but not vbscript.

So, as more universal version could construct JScript code, but I haven't done that yet. The alternative is to use an "about:<script type=text/vbs> ... </script> construct, which I have done in the past. In fact, I jsut played with a login GUI application that returns its results to the calling batch procedure ...

:: PWGUI.cmd, Tom Lavedas 12/06/2012
@echo off & setlocal

set "scr=<hta:application sysmenu=no contextmenu=no />"
set "scr=%scr%<title>Login</title>"
set "scr=%scr%<script type=text/vbs>"
set "scr=%scr%resizeTo 300,150:"
set "scr=%scr%sub ok_onclick:"
set "scr=%scr%createobject("scripting.filesystemobject")."
set "scr=%scr%GetStandardStream(1).write UID.value&chr(32)&PW.value:"
set "scr=%scr%close:end sub"
set "scr=%scr%</script>"
set "scr=%scr%<body scroll=no bgcolor=#dfdfdf onload=uid.focus>"
set "scr=%scr%<span style=width:75>UserID:</span>"
set "scr=%scr%<input type=text id=UID style=width:150></br>"
set "scr=%scr%<span style=width:75>Password:</span>"
set "scr=%scr%<input type=password id=pw style=width:150><hr>"
set "scr=%scr%<center><input type=submit id=OK value=OK>"

for /f "tokens=1,2" %%a in ('mshta "about:%scr%"') do echo UID:%%a, PW:%%b

One note, the command line length limitation restricts the size of script that can be used. I ran into that limitation with earlier versions of the script above in Win7, when I tried to add some bells and whistles. That is one of the reasons some of the HTML tags that would normally be used are left off. The host supplies these as it interprets the supplied code. So, to reduce character count, I removed them.
_____________________________
Tom Lavedas

Tom Lavedas

unread,
Dec 7, 2012, 10:42:46 AM12/7/12
to
On Friday, December 7, 2012 8:51:36 AM UTC-5, Tom Lavedas wrote:
> On Thursday, December 6, 2012 8:23:23 PM UTC-5, Auric__ wrote:
> Tom Lavedas wrote:

> A more universal version could [be] construct[ed in] JScript code

OK, here is the JScript version, which should work today and back to IE5, at least.

Both the command prompt and file version of a macro:

js=for /f "delims=" %a in ('mshta "javascript:with(new ActiveXObject('scripting.filesystemobject'))GetStandardStream(1).write($*);close()"') do @echo.%a

Batch version:

:: JSC.cmd, Tom Lavedas 12/07/2012
@echo off & setlocal
set "JSC=javascript: with(new ActiveXObject('scripting.filesystemobject'))"
set "JSC=%JSC%GetStandardStream(1).write(%*);close()"
for /f "delims=" %%a in ('mshta "%JSC%"') do echo.%%a
:: Examples
::
:: @for /f %T in ('jsc Date(^)') do set Today=%T
::
:: @for /f %P in ('jsc 4*Math.atan(1^)') do set PI = %P
::
:: This form just displays the results
:: jsc Math.sqrt(2)

Note that JScript IS case sensitive. Also, the Date() object is very tricky to work with. This is as far as I've gotten in constructing Yesterday's date (at the command line using the macro version) ...

js (new Date().getMonth()+1)+'/'+(new Date().getDate()-1)+'/'+new Date().getYear()

It doesn't pad the month and date with zeros yet, but the following does in a YYYYMMDD format ...

js (new Date().getMonth()+1)*100+(new Date().getDate()-1)+new Date().getYear()*10000
_______________________________
Tom Lavedas

Frank Westlake

unread,
Dec 7, 2012, 3:23:12 PM12/7/12
to
It appears that you are on Christmas vacation and that none of your
children are still living with you Tom. You have time to play.

On 2012-12-07 07:42, Tom Lavedas wrote:
> js (new Date().getMonth()+1)+'/'+(new Date().getDate()-1)+'/'+new Date().getYear()

Here's how you can reuse the same Date object to save a few microseconds:

jsc ((D=new Date()).getMonth()+1)+'/'+(D.getDate()-1)+'/'+D.getYear()

Frank

Tom Lavedas

unread,
Dec 7, 2012, 3:57:52 PM12/7/12
to
On Friday, December 7, 2012 3:23:12 PM UTC-5, Frank Westlake wrote:
>
> It appears that you are on Christmas vacation and that none of your children
> are still living with you Tom. You have time to play.
>

Sort of. It's a year end lull at work. Don't tell the boss ;0)

> On 2012-12-07 07:42, Tom Lavedas wrote:
> js (new Date().getMonth()+1)+'/'+(new Date().getDate()-1)+'/'+new Date().getYear()
>
> Here's how you can reuse the same Date object to save a few microseconds:
>
> jsc ((D=new Date()).getMonth()+1)+'/'+(D.getDate()-1)+'/'+D.getYear()
>
> Frank

Thanks, Frank. That's sweet. Not being much of a JScript type, I didn't realize that was possible. I had assumed (and confirmed) that I couldn't set a variable as a separate statement, because of the placement within the argument list of another function (the write()). I never even imagined it could be done imbedded in that way. I learned something.
_________________________
Tom Lavedas

frank.w...@gmail.com

unread,
Dec 7, 2012, 6:14:58 PM12/7/12
to
From Tom Lavedas :
>Not being much of a
>JScript type, I didn't realize that was possible.

It's a C language thing; inherited by Java, JavaScript,
and JScript. Notice that D isn't first declared as
'var'. That's permitted in the two interpreted languages
but not the two compiled languages. The variable D
becomes a type of global variable with some differences
from 'var D' being defined globally. These are both
global but different:

var G=5;
D=6;

I don't recall what the differences are but they might
not be the same with both JScript and JavaScript.

Another similarity of the four languages is that an
assigmnent returns a value that can be simultaneously
made use of. This permits things like:

var a, b, c;
a=b=c=5;
a=3*(b=2*(c=5));// a=30, b=10, c=5.

This ability to chain the result of an assignment
extends to the Java-like dot operator:

var D;
var H=(D=new Date()).getHours();

Off topic so I hope this isn't burdensome.

Frank

Dr J R Stockton

unread,
Dec 8, 2012, 12:54:27 PM12/8/12
to
In alt.msdos.batch.nt message <431fef83-35a7-4537-b6ff-914fda098e5d@goog
legroups.com>, Fri, 7 Dec 2012 07:42:46, Tom Lavedas
<tglb...@verizon.net> posted:

>
>Note that JScript IS case sensitive. Also, the Date() object is very tricky to work with. This is as far as I've gotten in constructing
>Yesterday's date (at the command line using the macro version) ...
>
>js (new Date().getMonth()+1)+'/'+(new Date().getDate()-1)+'/'+new Date().getYear()
>
>It doesn't pad the month and date with zeros yet, but the following does in a YYYYMMDD format ...
>
>js (new Date().getMonth()+1)*100+(new Date().getDate()-1)+new Date().getYear()*10000

You are a Batch expert.

You are very obviously not a JScript or JavaScript expert, and you
should not post J* code here until you have learned a great deal more
about J* unless you want to destroy the residue of your general
reputation.

That will fail on the first of each month.
That will fail if run across midnight.
Method getYear is deprecated. It will do what you want in MS IE, but
not currently in other major browsers, which comply with the standard.

Read <http://www.merlyn.demon.co.uk/js-dates.htm>, and all the relevant
pages on the same site that it links to, and the also-linked ECMA
standard. RSVP on any errors you find.

OTOH, one of the USA's most famous national labs, one IIRC under the
aegis of c..T..h, used for many years something even sillier.

Frank's followup fixes the second fault, but not the others.


J* new Date() should only be used once to capture the value of the
current instant. To merely create a Date Object, use new Date(0)
(rarely needed, though).

--
(c) John Stockton, nr London, UK. E-mail, see Home Page. Turnpike v6.05.
Website <http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc. : <http://www.merlyn.demon.co.uk/programs/> - see in 00index.htm
Dates - miscdate.htm estrdate.htm js-dates.htm pas-time.htm critdate.htm etc.

frank.w...@gmail.com

unread,
Dec 8, 2012, 7:06:02 PM12/8/12
to
Doc, I think it's time you should seriously consider
retiring from public correspondence.

Frank

Todd Vargo

unread,
Dec 9, 2012, 11:31:14 AM12/9/12
to
On 12/8/2012 12:54 PM, Dr J R Stockton wrote:
> In alt.msdos.batch.nt message <431fef83-35a7-4537-b6ff-914fda098e5d@goog
> legroups.com>, Fri, 7 Dec 2012 07:42:46, Tom Lavedas
> <tglb...@verizon.net> posted:
>
>>
>> Note that JScript IS case sensitive. Also, the Date() object is very tricky to work with. This is as far as I've gotten in constructing
>> Yesterday's date (at the command line using the macro version) ...
>>
>> js (new Date().getMonth()+1)+'/'+(new Date().getDate()-1)+'/'+new Date().getYear()
>>
>> It doesn't pad the month and date with zeros yet, but the following does in a YYYYMMDD format ...
>>
>> js (new Date().getMonth()+1)*100+(new Date().getDate()-1)+new Date().getYear()*10000
<snip>

> That will fail on the first of each month.
> That will fail if run across midnight.
<snip>

> J* new Date() should only be used once to capture the value of the
> current instant.

You have a keen eye for date/time related code, but for who you are
directing your message to, these statements above are all that needed
mentioned (although same concept applies to all programming languages).

--
Todd Vargo
(Post questions to group only. Remove "z" to email personal messages)

Tom Lavedas

unread,
Dec 10, 2012, 8:42:43 AM12/10/12
to
On Saturday, December 8, 2012 12:54:27 PM UTC-5, Dr J R Stockton wrote:

> You are very obviously not a JScript or JavaScript expert.

Never made that claim. In fact, I have issued that disclaimer several times here and elsewhere in my posts, though I failed to do that in this particular thread, sorry).

> That will fail on the first of each month.

You are absolutely correct. Looking back at it, it's obvious - and it makes this approach wholely unsatisfactory. HOWEVER, I seem to have missed your code that corrects my obvious shortcomings.

As Todd said, you are clearly an expert in all matters related to time and date, but your condescending attitude works against your efforts to educate the rest of us and, frankly, I don't appreciate it. It generally keeps me from reading anything you post.
___________________________
Tom Lavedas

Tom Lavedas

unread,
Dec 10, 2012, 9:22:10 AM12/10/12
to
On Monday, December 10, 2012 8:42:43 AM UTC-5, Tom Lavedas wrote:

PS.

jsc ((D=new Date(new Date()-86400000)).getMonth()+1)*100+D.getDate()+D.getFullYear()*10000
________________________________
Tom Lavedas

Frank Westlake

unread,
Dec 10, 2012, 9:42:41 AM12/10/12
to
On 2012-12-10 06:22, Tom Lavedas wrote:
> jsc ((D=new Date(new Date()-86400000)).getMonth()+1)*100+D.getDate()+D.getFullYear()*10000

jsc (S=(((D=new Date(new
Date()-86400000)).getMonth()+1)*100+D.getDate()+D.getFullYear()*10000)+"").substr(0,4)+"-"+S.substr(4,2)+"-"+S.substr(6,2)

CAVEAT: I'm not an expert at anything.

Maybe I should add that to my signature.

Frank

Tom Lavedas

unread,
Dec 10, 2012, 10:34:55 AM12/10/12
to
Thanks, that's a useful addition to my examples.

As long as I'm here, I'll mention that using a FOR statement to collect the result into the environment of this kind of expression requires the escaping of BOTH the closing parens AND the equal signs, that is ...

for /f %Y in (
'jsc (S^=(((D^=new Date(new Date(^) ... +S.substr(6,2^)'
) do set Yesterday=%Y
__________________________________
Tom Lavedas

Dr J R Stockton

unread,
Dec 10, 2012, 2:23:15 PM12/10/12
to
In alt.msdos.batch.nt message <ka2eci$e0r$1...@news.albasani.net>, Sun, 9
Dec 2012 11:31:14, Todd Vargo <tlv...@sbcglobal.netz> posted:
Your ignorance matches the other ignorance. Evidently you are a code
writer and not a code tester.

Yours is a common error; of considering or testing a few cases that work
and assuming that all others will work correctly.

An RFC draft author did this, before 2000, implementing Zeller's
Congruence in C. His version works for all dates, except for a few in
certain months early in each century. But who in the 1990s would test
dates in the 2xxxs? Zeller, of course knew (but did not always write)
better; he understood the situation, without using a computer. But no
loyal redneck looks at original material, especially if in German or
Latin. I mailed the author, and the RFC was corrected.

Todd Vargo

unread,
Dec 11, 2012, 1:46:02 PM12/11/12
to
As a group reader, I do not get paid to perform either. I test every bit
of code that I use personally. It is up to the individual reader to
perform their own testing on whatever code they choose to copy from a
newsgroup.

>
> Yours is a common error; of considering or testing a few cases that work
> and assuming that all others will work correctly.

See above.

>
> An RFC draft author did this, before 2000, implementing Zeller's
> Congruence in C. His version works for all dates, except for a few in
> certain months early in each century. But who in the 1990s would test
> dates in the 2xxxs? Zeller, of course knew (but did not always write)
> better; he understood the situation, without using a computer. But no
> loyal redneck looks at original material, especially if in German or
> Latin. I mailed the author, and the RFC was corrected.

The difference being, said author received private mail, not public
diatribe.

Dr J R Stockton

unread,
Dec 11, 2012, 10:58:10 AM12/11/12
to
In alt.msdos.batch.nt message <ka4sd2$m3l$1...@news.albasani.net>, Mon, 10
Dec 2012 06:42:41, Frank Westlake <frank.w...@gmail.com> posted:

>On 2012-12-10 06:22, Tom Lavedas wrote:
>> jsc ((D=new Date(new Date()-86400000)).getMonth()+1)*100+D.getDate()+
>>D.getFullYear()*10000
>
>jsc (S=(((D=new Date(new Date()-86400000)).getMonth()+1)*100+D.getDate(
>)+D.getFullYear()*10000)+"").substr(0,4)+"-"+S.substr(4,2)+"-"+S.substr
>(6,2)
>
>CAVEAT: I'm not an expert at anything.


Fails about 1/(24*183) of the time in many locations, but half that
number in LHI (for any JavaScript system that understands LHI). OK, I
think, during popular working hours.

You (plural) are not even making new mistakes; all of yours are old hat
in news:CLJ.

As a minor point, 864e5 is better than 86400000, since one does not then
need to be careful about the number of zeroes. But, here, both are
wrong.

Read ECMA 262, 5th edition, obtained at delightful cost from ECMA.


Response to previous post : My aim is not to educate you, it is to
inhibit you from mis-educating others. Him with head in sand leaves
arse showing.

You should learn JavaScript, including the use of the Date Object, and
then write about it. In that order.

--
(c) John Stockton, nr London UK Reply address via Home Page.
news:comp.lang.javascript FAQ <http://www.jibbering.com/faq/index.html>.
<http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

frank.w...@gmail.com

unread,
Dec 12, 2012, 5:45:00 AM12/12/12
to
From Dr J R Stockton :
>Response to previous post : My aim is not to educate
>you, it is to
>inhibit you from mis-educating others.


In that mission you will always fail. It is not possible
to always get everything right and people will always
learn from our wrongs as well as our rights. You can't
stop that. You may hope to reduce the amount of
mis-education through education, but your demeanor is
causing a greater and more harmful mis-education.

Frank

Dr J R Stockton

unread,
Dec 12, 2012, 7:22:44 AM12/12/12
to
In alt.msdos.batch.nt message <ka7v10$mm2$1...@news.albasani.net>, Tue, 11
Dec 2012 13:46:02, Todd Vargo <tlv...@sbcglobal.netz> posted:
You endorsed the "these statements above", thereby sharing
responsibility for the accuracy of their content. Granted that one does
not need any *more* statements; one just needs the code to be correct.


>> Yours is a common error; of considering or testing a few cases that work
>> and assuming that all others will work correctly.
>
>See above.

Clearly you did not think before you wrote. The errors would be evident
to the meanest intelligence, if it were applied.


>> An RFC draft author did this, before 2000, implementing Zeller's
>> Congruence in C. His version works for all dates, except for a few in
>> certain months early in each century. But who in the 1990s would test
>> dates in the 2xxxs? Zeller, of course knew (but did not always write)
>> better; he understood the situation, without using a computer. But no
>> loyal redneck looks at original material, especially if in German or
>> Latin. I mailed the author, and the RFC was corrected.
>
>The difference being, said author received private mail, not public
>diatribe.

He did not post in a discussion medium; and his document was a draft.
Also, his error was in the original sources (perhaps you do not read
German or Latin, and do not know where to look for my translation and
full testing) together with the necessary modification. To perceive the
error, read <http://www.ietf.org/rfc/rfc3339.txt> altering in your mind
the only instance of the five characters + 5 * to - 2 * .

Todd Vargo

unread,
Dec 13, 2012, 12:11:31 AM12/13/12
to
On 12/12/2012 7:22 AM, Dr J R Stockton wrote:
<snip>
>
> He did not post in a discussion medium; and his document was a draft.
> Also, his error was in the original sources (perhaps you do not read
> German or Latin, and do not know where to look for my translation and
> full testing) together with the necessary modification. To perceive the
> error, read <http://www.ietf.org/rfc/rfc3339.txt> altering in your mind
> the only instance of the five characters + 5 * to - 2 * .

You (and those involved) seem to have missed an important omission from
rfc3339; which is the very basis that you posted to this discussion.
IMO, rfc3339 should include the following.

Appendix D. Calculations

When calculations are to be performed on a computers current date/time,
to prevent miscalculations from occurring as date/time continues to
increment while the calculation is being performed, the current
date/time must be stored and all calculations be performed on the stored
value.

Dr J R Stockton

unread,
Dec 13, 2012, 10:12:34 AM12/13/12
to
In alt.msdos.batch.nt message <13b8ec1ce13$frank.w...@gmail.com>,
Wed, 12 Dec 2012 10:45:00, frank.w...@gmail.com posted:
It is a great pity that you do not understand English. The word
"inhibit" does not mean "prevent".

The best way for people to learn from your wrongs is by seeing the
criticisms of them that others give. Subtle errors should be and
usually are treated gently; you should not expect the same for your
crass follies.

--
(c) John Stockton, nr London UK. ???@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Check boilerplate spelling -- error is a public sign of incompetence.
Never fully trust an article from a poster who gives no full real name.

Dr J R Stockton

unread,
Dec 14, 2012, 1:23:28 PM12/14/12
to
In alt.msdos.batch.nt message <kabo24$ml2$1...@news.albasani.net>, Thu, 13
Dec 2012 00:11:31, Todd Vargo <tlv...@sbcglobal.netz> posted:
No. The authors of RFCs, being human, do make mistakes; but they are
writing for a reasonably intelligent readership, at least by US male
standards. Moreover, the RFC deals with date/time formatting, not
date/time measurement or calculation. Remember Mark Twain.

Todd Vargo

unread,
Dec 15, 2012, 8:15:11 AM12/15/12
to
On 12/14/2012 1:23 PM, Dr J R Stockton wrote:
> In alt.msdos.batch.nt message <kabo24$ml2$1...@news.albasani.net>, Thu, 13
> Dec 2012 00:11:31, Todd Vargo <tlv...@sbcglobal.netz> posted:
>
>> On 12/12/2012 7:22 AM, Dr J R Stockton wrote:
>> <snip>
>>>
>>> He did not post in a discussion medium; and his document was a draft.
>>> Also, his error was in the original sources (perhaps you do not read
>>> German or Latin, and do not know where to look for my translation and
>>> full testing) together with the necessary modification. To perceive the
>>> error, read <http://www.ietf.org/rfc/rfc3339.txt> altering in your mind
>>> the only instance of the five characters + 5 * to - 2 * .
>>
>> You (and those involved) seem to have missed an important omission from
>> rfc3339; which is the very basis that you posted to this discussion.
>> IMO, rfc3339 should include the following.
>>
>> Appendix D. Calculations
>>
>> When calculations are to be performed on a computers current date/time,
>> to prevent miscalculations from occurring as date/time continues to
>> increment while the calculation is being performed, the current
>> date/time must be stored and all calculations be performed on the
>> stored value.
>
>
> No. The authors of RFCs, being human, do make mistakes; but they are
> writing for a reasonably intelligent readership, at least by US male
> standards. Moreover, the RFC deals with date/time formatting, not
> date/time measurement or calculation. Remember Mark Twain.

Based on your autocratic assertion, appendix B & C have nothing to do
with formatting either and should therefore be omitted. You would do
well to discuss these matters with some open minded technical writers,
instead of playing your flame war games.

dbenham

unread,
Dec 16, 2012, 10:19:06 AM12/16/12
to
On Thursday, December 6, 2012 10:48:34 AM UTC-5, Tom Lavedas wrote:
>
> But for better presentation and easier maintenance, I would propose this ...
>
>
> :: VBS.cmd, Tom Lavedas 12/0620012
> @echo off & setlocal
> set VBS=vbscript:Execute("createobject(""scripting.filesystemobject"")
> set VBS=%VBS%.GetStandardStream(1).writeline
> for /f "delims=" %%a in ('mshta %VBS%(%*)"^^^&close^)') do echo.%%a
> ::
> :: Examples
> ::
> :: Display ASCII equivalents (in hex) for first 127 characters ...
> :: @for /l %N in (1,1,127) do @vbs right(""00""+hex(""%N"")+"":"",4)+chr(%N)
> ::
> :: @for /f %Y in ('vbs date-1') do set Yesterday=%Y
> ::
> :: @for /f %P in ('vbs 4*atn(1^)') do echo PI = %P
> ::
> :: @for /f %S in ('vbs sqr(2^)') do echo Sq Root of2 = %S
>

Nice :)

It should work on any Windows OS as long as IE is installed.

There is no need for an external VBS.BAT file. Simply define variables as batch "macros". The code still reads well.

:: BEGIN SCRIPT :::::::::::::::::::::::::::::::::::::::::::::::
@echo off
setlocal
:: Define simple batch "macros" to implement VBS within batch
set "vbsBegin='mshta vbscript:Execute("createobject(""scripting.filesystemobject"")"
set "vbsBegin=%vbsBegin%.GetStandardStream(1).write("
set ^"vbsEnd=):close"^)'"

:: Get yesterday's date
for /f %%Y in (%vbsBegin% date-1 %vbsEnd%) do set Yesterday=%%Y
set Yesterday
pause
echo(

:: Get pi
for /f %%P in (%vbsBegin% 4*atn(1) %vbsEnd%) do set PI=%%P
set PI
pause
echo(

set "var=name=value"
echo Before - %var%
:: Replace =
for /f "delims=" %%S in (
%vbsBegin% replace(""%var%"",""="","": "") %vbsEnd%
) do set "var=%%S"
echo After - %var%
pause
echo(

echo Extended ASCII:
for /l %%N in (0,1,255) do (

%= Get extended ASCII char, except can't work for 0x00, 0x0A. =%
%= Quotes are only needed for 0x0D =%
%= Enclosing string quote must be coded as "" =%
%= Internal string quote must be coded as """" =%
for /f delims^=^ eol^= %%C in (
%vbsBegin% """"""""+chr(%%N)+"""""""" %vbsEnd%
) do set "char.%%N=%%~C"

%= Display result =%
if defined char.%%N (
setlocal enableDelayedExpansion
echo( %%N: [ !char.%%N! ]
endlocal
) else echo( %%N: Doesn't work :(
)
pause
:: END SCRPT :::::::::::::::::::::::::::::::::::::::::::::::


But I am puzzled. I can't figure out why this technique works when executed via FOR /F, but it doesn't work when executed directly via CMD /C (which is how FOR /F executes commands). In the script below I have removed the single quotes from the "macros"

:: BEGIN SCRIP ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
setlocal
:: Define simple batch "macros" to implement VBS within batch
set "vbsBegin=mshta vbscript:Execute("createobject(""scripting.filesystemobject"")"
set "vbsBegin=%vbsBegin%.GetStandardStream(1).write("
set ^"vbsEnd=):close"^)"

:: This works
for /f "delims=" %%Y in ('%vbsBegin% ""Hello world"" %vbsEnd%') do echo %%Y
pause

:: This does not work. WHY?
cmd /c %vbsBegin% ""Hello world"" %vbsEnd%
:: END SCRIP ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


Dave Benham

Tom Lavedas

unread,
Dec 16, 2012, 1:44:03 PM12/16/12
to
On Sunday, December 16, 2012 10:19:06 AM UTC-5, dbenham wrote:
> On Thursday, December 6, 2012 10:48:34 AM UTC-5, Tom Lavedas wrote:

> But I am puzzled. I can't figure out why this technique works when executed via FOR /F, but it doesn't work when executed directly via CMD /C (which is how FOR /F executes commands). I
>
> :: This does not work. WHY?
>
> cmd /c %vbsBegin% ""Hello world"" %vbsEnd%
>
> :: END SCRIP

> Dave Benham

I don't know. It puzzled me when I first developed the approach, but not finding a reason, I just let it go. Clearly the FOR processing differs in some substantive way from that of cmd /c. It's just not clear to me what that might be. Maybe someone more capable than me can answer that.
______________________
Tom Lavedas

Frank Westlake

unread,
Dec 16, 2012, 3:31:57 PM12/16/12
to
On 2012-12-16 10:44, Tom Lavedas wrote:
> It puzzled me when I first developed the approach,
> but not finding a reason, I just let it go.

It puzzled me to when I first saw your development of the approach. I
recalled something about FOR redirecting streams but there didn't seem
to be a need to explore it so I didn't.

Apparently MSHTA checks the standard output stream to see if it is not
being redirected. If it is redirected the error message and console
could hang the procedure for an indefinite time so it skips them and
returns it's best guess at what was intended.

A demonstration; redirect the output stream:

cmd /c %vbsBegin% ""Hello world"" %vbsEnd% >junk & type junk

Frank

Dr J R Stockton

unread,
Dec 16, 2012, 11:37:47 AM12/16/12
to
In alt.msdos.batch.nt message <kaht4s$3nl$1...@news.albasani.net>, Sat, 15
Dec 2012 08:15:11, Todd Vargo <tlv...@sbcglobal.netz> posted:
Appendix B is needed to be able to take a date expressed in D M Y and
format it to, for example, Y M D DoW where DoW is day-of-week.

Appendix C is useful for those in, for example, a California where the
Gregorian Calendar Rules are not understood. The algorithm is correct,
though not necessarily the most efficient; but the comment is wrong (or
written in an unreliable dialect).

Grow up.

Todd Vargo

unread,
Dec 16, 2012, 7:43:32 PM12/16/12
to
Status quo maintained. Bully!

dbenham

unread,
Dec 16, 2012, 9:54:49 PM12/16/12
to
Excellent. That puts my mind more at ease.

It also works with a pipe

cmd /c %vbsBegin% ""Hello world"" %vbsEnd% | findstr "^"

I've seen Carlos refer to a FOR /F as being a pipe, and it puzzled me. It makes more sense now.

Dave Benham

dbenham

unread,
Dec 16, 2012, 10:03:56 PM12/16/12
to
On Sunday, December 16, 2012 9:54:49 PM UTC-5, dbenham wrote:
>
> I've seen Carlos refer to a FOR /F as being a pipe, and it puzzled me. It makes more sense now.
>

Upon further reflection, I think FOR /F is more likely redirecting output to a temp file and then reading it back in. Pipes can work asynchronously in parallel, but FOR /F always waits for the command to finish in its entirety before processing the first line.

Dave Benham

frank.w...@gmail.com

unread,
Dec 17, 2012, 3:42:12 AM12/17/12
to
From dbenham :
>Upon further reflection, I think FOR /F is more likely
>redirecting output to a temp file and then reading it
>back in. Pipes can work asynchronously in parallel, but
>FOR /F always waits for the command to finish in its
>entirety before processing the first line.

FOR/F has three read sources: file (%file%), string
("string"), and command ('TYPE file'). When reading a
file it processes each line before reading further. When
reading a command it waits until the output stream is
closed before processing it. The output is stored in
memory and probably does not normally get cached to
disc. When reading strings it is probably the same as
when reading a command but I haven't tested it.

Frank

Tom Lavedas

unread,
Dec 17, 2012, 9:59:02 AM12/17/12
to
On Monday, December 17, 2012 3:42:12 AM UTC-5, frank.w...@gmail.com wrote:
> From dbenham :

I'm glad you guys figured out the reason for the behaviour. With that insight to lead me, I've found that the cmd /c part is not required, either, as long as there is a redirection or pipe associated with the StdOut stream. Without that the GetStandardStream() function fails with an "Invalid handle" error. That is, this works fine ...

%vbsBegin% ""Hello world"" %vbsEnd% | more

So, that means the VBS.cmd can be simplified to this ...

:: VBS.cmd, Tom Lavedas 12/07/2012, 12/17/2012
@echo off & setlocal
set VBS="createobject(""scripting.filesystemobject"")
set VBS=%VBS%.GetStandardStream(1).write(%*):close"
mshta.exe vbscript:Execute(%VBS%^) | more

And the macro definition (one line)...

doskey vb=mshta vbscript:Execute("createobject(""""scripting.filesystemobject"""").GetStandardStream(1).write($*):close")^|more

Now, if we could only figure out how to easily keep mshta.exe from opening its window in the foreground to eliminate the display 'flash' when the procedure executes.
_______________________________
Tom Lavedas

Tom Lavedas

unread,
Dec 17, 2012, 2:01:36 PM12/17/12
to
On Monday, December 17, 2012 9:59:02 AM UTC-5, Tom Lavedas wrote:
>> On Monday, December 17, 2012 3:42:12 AM UTC-5, frank.w...@gmail.com wrote:
>>> From dbenham :

> I'm glad you guys figured out the reason for the behaviour.

OK, that insight also leads to this extension of the concept that will also process input, redirected or piped ...

:: VBSIO.cmd, Tom Lavedas 12/10/2012, 12/17/2012
@echo off & setlocal
set "VBS=with createobject(""scripting.filesystemobject""):"
set "VBS=%VBS%set i=.GetStandardStream(0):"
set "VBS=%VBS%set o=.GetStandardStream(1):"
set "VBS=%VBS%do until i.atendofstream:n=cstr(n+1):"
set "VBS=%VBS%s=i.readline:"
set "VBS=%VBS% %* :"
set "VBS=%VBS%o.writeline(s):loop:end with:close"
more | mshta.exe vbscript:Execute("%VBS%") | findstr .*

For example, to line number the output text from some command (uses the predefined script variables n & s) ...

command | vbsio s=n+chr(9)+s

To do it with padded numbering ...

command | vbsio s=right(""000""+n,4)+chr(9)+s

With two caveats, this procedure can replace VBS.cmd. That is, 1) it must be supplied with some form of input on StdIn; either redirected or piped. If no input is needed, then the NUL device needs to be redirected into it. And 2) the result must end up in the variable, s. For example, ...

vbsio s=4*atn(1) < nul

This formulation can create intermmediate variables and accept multiple script statements separtated from each other by a colon. For example, ...

vbsio pi=4*atn(1):s=""PI=""+cstr(pi) < nul

Finally, note that I replaced the second MORE on the last statement with a FINDSTR. The MORE was adding an extra blank line to the output, which the FINDSTR does not.
____________________________
Tom Lavedas

dbenham

unread,
Dec 17, 2012, 11:11:51 PM12/17/12
to
On Monday, December 17, 2012 2:01:36 PM UTC-5, Tom Lavedas wrote:
>
> more | mshta.exe vbscript:Execute("%VBS%") | findstr .*
>
> Finally, note that I replaced the second MORE on the last statement with a FINDSTR. The MORE was adding an extra blank line to the output, which the FINDSTR does not.
>

The * is not needed, you just need FINDSTR to match a single character.

But . is not the best choice since it cannot match a blank line (doesn'nt match <cr> or <lf>).

I recommend FINDSTR "^"
It will match all lines of input, and never alters the input, other than appending line feed if the last line of input does not already end with line feed.

There is one potential issue with FINDSTR on XP - it will display most control characters and many extended ASCII chars as dots on XP unless the output is redirected, piped, or captured by FOR /F.

Another problem with MORE is it converts tabs into spaces (8 by default).

Tom Lavedas

unread,
Dec 18, 2012, 8:38:09 AM12/18/12
to
On Monday, December 17, 2012 11:11:51 PM UTC-5, dbenham wrote:
> On Monday, December 17, 2012 2:01:36 PM UTC-5, Tom Lavedas wrote:
>
> more | mshta.exe vbscript:Execute("%VBS%") | findstr .*
>

> Finally, note that I replaced the second MORE on the last statement with a
> FINDSTR. The MORE was adding an extra blank line to the output, which the
> FINDSTR does not.
>

<quote>
The * is not needed, you just need FINDSTR to match a single character.

But . is not the best choice since it cannot match a blank line (doesn'nt match <cr> or <lf>).

I recommend FINDSTR "^"
It will match all lines of input, and never alters the input, other than appending line feed if the last line of input does not already end with line feed.

There is one potential issue with FINDSTR on XP - it will display most control characters and many extended ASCII chars as dots on XP unless the output is redirected, piped, or captured by FOR /F.

Another problem with MORE is it converts tabs into spaces (8 by default).
</quote>

Thanks for your input. In my experience, the added asterisk after the dot assures that blank lines are included in the output. This overcomes the acknowledged problem with using a single dot. Though, as with all the peculiarities of command line processing, this can become a 'feature' under the right circumstances. On the otherhand, using a dollar sign might be better than any of the alternatives. It takes fewer keystrokes ;o).

Regarding tab expansion, my experience (in Win7) is that MORE does not expand tabs unless the /T switch is used. In addition, the /Tn switch provides an interesting feature in that it enables the padding of lines with a variable number of spaces - offering the ability to alter the spacings between tabbed columns.

I guess it all depends on your needs.
________________________________
Tom Lavedas

Frank Westlake

unread,
Dec 18, 2012, 10:11:49 AM12/18/12
to
On 2012-12-18 05:38, Tom Lavedas wrote:
> In my experience, the added asterisk after the dot assures that blank lines are included in the output.

They must've changed it. On W8 the following prints lines with or
without endings and also blank lines, both on the command line and by
script:

(
Echo Line 1 -- blank follows
Echo;
Echo Line 3 -- there it was!
Set /P "=Line 4 -- no endline."<NUL:
)|FindStr ".*"|FindStr "."|FindStr "^"|FindStr "$"|FindStr .


Frank

Tom Lavedas

unread,
Dec 18, 2012, 10:36:28 AM12/18/12
to
Try testing it with a simple 'DIR *.txt | findstr ...' (or some other file mask to limit the size of the output). That's what I tested with and got different results, depending on the match string I used in Win 7.

One change is that in Win7 the version without arguments fails with a "Bad command" error.
_________________________
Tom Lavedas

Frank Westlake

unread,
Dec 18, 2012, 10:41:27 AM12/18/12
to
On 2012-12-18 07:36, Tom Lavedas wrote:
>> On Tuesday, December 18, 2012 10:11:49 AM UTC-5, Frank Westlake wrote:
>> They must've changed it. On W8 the following prints lines with or
>> without endings and also blank lines, both on the command line and by
>> script:
>>
>> (
>> Echo Line 1 -- blank follows
>> Echo;
>> Echo Line 3 -- there it was!
>> Set /P "=Line 4 -- no endline."<NUL:
>> )|FindStr ".*"|FindStr "."|FindStr "^"|FindStr "$"|FindStr .

> Try testing it with a simple 'DIR *.txt | findstr ...'

That skips blank lines. Later today I'll examine the hex output to see
if there's a difference in DIR's blanks and SET/P's blanks.

Frank

Frank Westlake

unread,
Dec 18, 2012, 10:42:25 AM12/18/12
to
On 2012-12-18 07:41, Frank Westlake wrote:
> That skips blank lines. Later today I'll examine the hex output to see
> if there's a difference in DIR's blanks and SET/P's blanks.

Correction:

... if there's a difference in DIR's blanks and ECHO's blanks.

Frank

frank.w...@gmail.com

unread,
Dec 18, 2012, 4:45:03 PM12/18/12
to
From Frank Westlake :
>That skips blank lines. Later today I'll examine the hex
>output to see if there's a difference...

The difference is that ECHO is appending a space to its
line when within a parenthesized block which goes to a
pipe, but not in the case of redirection:

ECHO A|hex
41 0D OA

(ECHO A)|hex
41 20 0D OA

ECHO;|hex
0D OA

(ECHO;)|hex
20 0D OA

(ECHO;&ECHO;)>junk
TYPE junk|hex
OD OA OD 0A

For those who don't read hex:

20 space
41 letter 'A'
0D carriage return
0A line feed

I suspect that this has been well known for a long time
but I have not needed to be aware of it until now.

Frank

dbenham

unread,
Dec 18, 2012, 5:20:46 PM12/18/12
to
On Tuesday, December 18, 2012 10:42:25 AM UTC-5, Frank Westlake wrote:
> On 2012-12-18 07:41, Frank Westlake wrote: > That skips blank lines. Later today I'll examine the hex output to see > if there's a difference in DIR's blanks and SET/P's blanks. Correction: ... if there's a difference in DIR's blanks and ECHO's blanks. Frank

Your test is flawed - it does not produce an empty line!

>> (
>> Echo Line 1 -- blank follows
>> Echo;
>> Echo Line 3 -- there it was!
>> Set /P "=Line 4 -- no endline."<NUL:
>> )|FindStr ".*"|FindStr "."|FindStr "^"|FindStr "$"|FindStr .

Both sides of the pipe are executed via CMD /C. The parser concatenates each line with & delimiters. Unfortunately the parser inserts a space before each &, so your empty line actually conatains a space.

I have done a LOT of research on FINDSTR - see <http://stackoverflow.com/q/8844868/1012053>

"." does not match <CR> or <LF>

"^" will match absolutely any line

"$" will match any line that contains <CR>.

Dave Benham

dbenham

unread,
Dec 18, 2012, 5:34:49 PM12/18/12
to
On Tuesday, December 18, 2012 4:45:03 PM UTC-5, frank.w...@gmail.com wrote:
> From Frank Westlake : >That skips blank lines. Later today I'll examine the hex >output to see if there's a difference... The difference is that ECHO is appending a space to its line when within a parenthesized block which goes to a pipe, but not in the case of redirection: ECHO A|hex 41 0D OA (ECHO A)|hex 41 20 0D OA ECHO;|hex 0D OA (ECHO;)|hex 20 0D OA (ECHO;&ECHO;)>junk TYPE junk|hex OD OA OD 0A For those who don't read hex: 20 space 41 letter 'A' 0D carriage return 0A line feed I suspect that this has been well known for a long time but I have not needed to be aware of it until now. Frank

Indeed :)

There are many quirks that result from the way pipes are implemented on Windows. Here is a good resource: <http://stackoverflow.com/q/8844868/1012053>
I don't think we explictly covered the inserted space issue in that Q&A, but the thread gives enough info such that you can see how it might occur.

Dave Benham

foxidrive

unread,
Dec 18, 2012, 8:50:09 PM12/18/12
to
On 19/12/2012 8:45 AM, frank.w...@gmail.com wrote:
> (ECHO;)|hex
> 20 0D OA

(ECHO;)>b

That creates a 2 byte file with 0d0a in it. No space.

Is your hex program accurate?

--
foxi

foxidrive

unread,
Dec 18, 2012, 8:53:45 PM12/18/12
to
On 19/12/2012 12:50 PM, foxidrive wrote:
> On 19/12/2012 8:45 AM, frank.w...@gmail.com wrote:
>> (ECHO;)|hex
>> 20 0D OA
>
> (ECHO;)>b
>
> That creates a 2 byte file with 0d0a in it. No space.
>


I see that Dave B has explained that a space is added in a pipe.



--
foxi

foxidrive

unread,
Dec 18, 2012, 8:57:50 PM12/18/12
to
On 19/12/2012 9:34 AM, dbenham wrote:
> On Tuesday, December 18, 2012 4:45:03 PM UTC-5, frank.w...@gmail.com wrote:
>> From Frank Westlake : >That skips blank lines. Later today I'll examine the hex >output to see if there's a difference... The difference is that ECHO is appending a space to its line when within a parenthesized block which goes to a pipe, but not in the case of redirection: ECHO A|hex 41 0D OA (ECHO A)|hex 41 20 0D OA ECHO;|hex 0D OA (ECHO;)|hex 20 0D OA (ECHO;&ECHO;)>junk TYPE junk|hex OD OA OD 0A For those who don't read hex: 20 space 41 letter 'A' 0D carriage return 0A line feed I suspect that this has been well known for a long time but I have not needed to be aware of it until now. Frank

Google groups has a lot to answer for.

Some posts are concatenated like above, some posts are double spaced.

Ahhhhhhhhhhhhhhhhhhhgh!



--
foxi

Frank Westlake

unread,
Dec 19, 2012, 10:35:05 AM12/19/12
to
On 2012-12-18 14:34, dbenham wrote:
> Here is a good resource: <http://stackoverflow.com/q/8844868/1012053>

Very good. Determine the cost of that document according to the amount
of time you put into it and send MicroSoft a bill. Send Bill a bill.

>Source of data to search
> Instead of searching contents of a file, FINDSTR can search
>• data stream from a pipe type file | findstr "searchString"
>• stdin via redirection findstr "searchString" <file

I'm not going there to participate in that forum so you may wish to this:

Also standard input without being redirected:

ECHO Who are you? Terminate input with CTRL-Z on a new line.
FINDSTR /I "Frank" >NUL: && (
Echo Permission granted.
) || (
Echo GO AWAY!!!
)

Frank

dbenham

unread,
Dec 19, 2012, 10:47:56 AM12/19/12
to
On Tuesday, December 18, 2012 8:38:09 AM UTC-5, Tom Lavedas wrote:
<quote> Thanks for your input. In my experience, the added asterisk after the dot assures that blank lines are included in the output. This overcomes the acknowledged problem with using a single dot.</quote>

I finally tested your ".*" and was initially shocked to see that it does match empty lines. But I have finally figured out why. The dot is a red herring - the key is the asterisk. The asterisk matches the prior character 0 or more times. The dot fails to match anything on an empty line, but the asterisk makes it OK to not match. There is nothing more to search, so the line matches.

It does not matter what character precedes the asterisk, it will always match any line. For example FINDSTR "X*" "filename" will also match all lines in "filename", including empty lines.

I see how it works, but my mind still rebels at the concept. The "^" is easier for me to digest.


<quote>On the otherhand, using a dollar sign might be better than any of the alternatives. It takes fewer keystrokes ;o).</quote>

My prior assertion is indeed true: "$" will fail to match lines that do not have a <CR>.


<quote>Regarding tab expansion, my experience (in Win7) is that MORE does not expand tabs unless the /T switch is used. In addition, the /Tn switch provides an interesting feature in that it enables the padding of lines with a variable number of spaces - offering the ability to alter the spacings between tabbed columns. I guess it all depends on your needs.</quote>

I ran a test on Windows 7, and MORE always converts <TAB> into 8 <SPACE> if the /T option is not specified. As far as I know, this is true for all versions of Windows, and there is no technique to prevent MORE from converting tabs into spaces.

Frank Westlake

unread,
Dec 19, 2012, 11:05:41 AM12/19/12
to
On 2012-12-19 07:47, dbenham wrote:
> I ran a test on Windows 7, and MORE always converts <TAB> into 8 <SPACE> if the /T option is not specified. As far as I know, this is true for all versions of Windows, and there is no technique to prevent MORE from converting tabs into spaces.

On my W8 machine, the script prints itself so you can see what its
doing, the is shown what it did:

C:\w>cmdtest
@Echo OFF
TYPE %~f0
ECHO BEGIN TEST.
ECHO;" "|hex
ECHO END TEST.

BEGIN TEST.
HEX: +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0123456789abcdef
0000000000: 22 09 22 0D 0A "."..
END TEST.

I am unable to enter tabs at the command line, probably because of the
command line completion feature. For the benefit of those who don't
speak hex:

09 tab character
0D carriage return
22 quote character
LF line feed

Frank

foxidrive

unread,
Dec 19, 2012, 11:08:31 AM12/19/12
to
On 20/12/2012 2:47 AM, dbenham wrote:

> I ran a test on Windows 7, and MORE always converts <TAB> into 8 <SPACE> if the /T option is not
> specified. As far as I know, this is true for all versions of Windows, and there is no technique to
> prevent MORE from converting tabs into spaces.

I confirm in Windows 8 that both these convert a tab character into spaces. FIVE spaces.

more filename >file2.txt
more<filename >file2.txt


--
foxi

Frank Westlake

unread,
Dec 19, 2012, 11:09:56 AM12/19/12
to
On 2012-12-19 08:05, Frank Westlake wrote:
Sorry, another flawed test. I forgot to include MORE in the pipe. With
that I get spaces:

HEX: +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0123456789abcdef
0000000000: 22 20 20 20 20 20 20 20 22 0D 0A 0D 0A "
"....END TEST.

knarF

Tom Lavedas

unread,
Dec 19, 2012, 11:10:25 AM12/19/12
to
On Wednesday, December 19, 2012 10:47:56 AM UTC-5, dbenham wrote:
> On Tuesday, December 18, 2012 8:38:09 AM UTC-5, Tom Lavedas wrote:

<quote> I ran a test on Windows 7, and MORE always converts <TAB> into 8 <SPACE> if the /T option is not specified. As far as I know, this is true for all versions of Windows, and there is no technique to prevent MORE from converting tabs into spaces.</quote>

I really thought I'd tested that, but I can't reproduce my previous result, so you are correct.
________________________
Tom Lavedas

foxidrive

unread,
Dec 19, 2012, 11:18:09 AM12/19/12
to
So it is the parentheses that cause a space to be added - the first one below doesn't add a space but the
bottom one does

d:\>ECHO;|sort>e

d:\>(ECHO;)|sort>e


--
foxi

foxidrive

unread,
Dec 19, 2012, 11:22:15 AM12/19/12
to
On 20/12/2012 2:47 AM, dbenham wrote:

> I ran a test on Windows 7, and MORE always converts <TAB> into 8 <SPACE> if the /T option is not
> specified. As far as I know, this is true for all versions of Windows, and there is no technique to
> prevent MORE from converting tabs into spaces.

I confirm in Windows 8 that both these convert a tab character into spaces. FIVE spaces.

more filename >file2.txt
more<filename >file2.txt


filename contains this - one tab before 123:
abc
def

ghi 123
hij
end of filename


--
foxi

foxidrive

unread,
Dec 19, 2012, 11:28:06 AM12/19/12
to
and if I place a TAB alone on the blank line it converts into 8 spaces - so it is indeterminate.

On 20/12/2012 2:47 AM, dbenham wrote:

> I ran a test on Windows 7, and MORE always converts <TAB> into 8 <SPACE> if the /T option is not
> specified. As far as I know, this is true for all versions of Windows, and there is no technique to
> prevent MORE from converting tabs into spaces.

Tom Lavedas

unread,
Dec 19, 2012, 11:41:06 AM12/19/12
to
On Wednesday, December 19, 2012 11:28:06 AM UTC-5, foxidrive wrote:
> and if I place a TAB alone on the blank line it converts into 8 spaces - so it is indeterminate.
-- foxi

It acts like a tab, which is what I would expect, with the exception that it pads with space to keep the previous alignment. If it were to always add eight spaces, it would be a real nusiance, IMHO.
_______________________
Tom Lavedas

foxidrive

unread,
Dec 19, 2012, 12:53:53 PM12/19/12
to
It all depends on the tab width of the document when it was created, I guess.

It's a damn nuisance anyway, if you expected the TABs for be preserved. (and I did up until now).


--
foxi
0 new messages