Hey, Scripting Guy! I need to write a command-line script that, given two arguments, can compare the two values and then – using standard errorlevel – report back whether string 1 is greater than or less than string 2, or if the two strings are identical. Can you help me with that?
Hey, JP. You know, in the past few days the sports world has been rocked by the revelation that Jason Giambi, first baseman for the New York Yankees, often wears a gold lamé, tiger-striped thong under his uniform in an attempt to help him break out of a slump. “I only wear it when I’m really desperate,” said Giambi, who must be about due to buy a new thong considering his current batting average of .191. Giambi also noted that, over the years, he has loaned his thong out to teammates Derek Jeter, Bernie Williams, Johnny Damon, Robin Ventura, and Robinson Cano. "All of them wore it and got hits," he said. "The thong works every time."
Of course, upon hearing this news most people immediately wondered, “Gee, does this mean that the Scripting Guys wear gold-lamé, tiger-striped thongs under their clothes every time they go into a slump?” As it turns out, the answer to that question is this: no, the Scripting Guys do not wear gold-lamé, tiger-striped thongs under their clothes every time they go into a slump.
But that’s mainly because the Scripting Guys have never actually gone into a slump. If we ever do, well, who knows?
Note. We should clarify that, when it comes to wearing wear gold-lamé, tiger-striped thongs, we’re talking solely about work and work-related activities. What Scripting Guy Dean Tsaltas may or may not do in the privacy of his own home is his own business.
Of course, upon hearing this news most people immediately wondered, “The Scripting Guys never go into a slump? How is that even possible?” Well, in part that’s possible because we never really do much; after all, if your normal day consists of doing nothing at all, well, it’s hard to fall into a slump and do even less than nothing. (Although if anyone could do less than nothing it’s the Scripting Guy who writes this column). However, it’s also because we’re able to come up with scripts that can compare two values and then report back whether string 1 is less than or greater than string 2, or whether the two values are identical.
You know, scripts just like this one:
strFirst = Wscript.Arguments(0) strSecond = Wscript.Arguments(1) intComparison = StrComp(strFirst, strSecond) If intComparison = -1 Then Wscript.Echo "String 1 is less than string 2." Wscript.Quit (1) ElseIf intComparison = 1 Then Wscript.Echo "String 1 is greater than string 2." Wscript.Quit (2) Else Wscript.Echo "The two strings are identical." Wscript.Quit (3) End If
Before we explain how the code works let’s take a look at the sample commands that JP included in his email:
CScript //NoLogo File.vbs 7.1 8.3b5-HP CScript //NoLogo File.vbs 8.3b5-HP 8.3b5-HP CScript //NoLogo File.vbs 9.2 8.3b5-HP
As you can see, what JP wants to do is start a script (in this case, a script named File.vbs) from the command prompt, passing that script two arguments. In his first example, those two arguments are the following:
He would like the script to compare the two values and then set the DOS errorlevel according to the following criteria: If the first string is “less than” the second (that is, when sorted alphabetically would string 1 come first) then he wants to set the errorlevel to 1. If the first string is greater than the second string he’d like to set the errorlevel to 2.
And what if the two strings are identical? Well, in that case, he’d like to set the errorlevel to 3. Can that be done? You bet it can.
Or at least we think it can. Let’s find out for sure.
We start out by using the following two lines of code to grab the arguments that were supplied when the script was started:
strFirst = Wscript.Arguments(0) strSecond = Wscript.Arguments(1)
As you probably know, each time you start a VBScript script any command-line arguments supplied when starting the script are automatically stored in the Wscript.Arguments collection. Because this is a “zero-based” collection that means that the first argument becomes argument 0, the second argument becomes argument 1, etc. In other words, the command strFirst = Wscript.Arguments(0) simply tells the script to take the first command-line argument (item 0 in the collection) and assign it to the variable strFirst. We then use the same process to assign the second command-line argument (item 1) to the variable strSecond.
That brings us to this line of code:
intComparison = StrComp(strFirst, strSecond)
What we’re doing here is using VBScript’s StrComp function to compare our two string values. By default, we’re doing a “binary comparison,” which is basically a case-sensitive comparison. In other words, the string value ABC is not the same as the string value abc. What if we wanted to do a case-insensitive comparison? No problem; all we have to do is add the optional parameter 1 to the end of our command:
intComparison = StrComp(strFirst, strSecond, 1)
Well, OK: and maybe we’d also put on a gold-lamé, tiger-striped thong. But that’s optional when working with the StrComp function.
StrComp is going to return one of three possible values:
-1, if the first string listed (strFirst) is less than the second string listed.
1, if the first string listed is greater than the second string listed.
0, if the two strings are identical.
What does that mean? Well, let’s go back to our first example:
CScript //NoLogo File.vbs 7.1 8.3b5-HP
In this case, the first string (7.1) is less than the second string (8.3b5-HP). Thus StrComp is going to return a -1. See how that works? Suppose the arguments were switched and we started the script with this command:
CScript //NoLogo File.vbs 8.3b5-HP 7.1
In this case StrComp would return a 1; that’s because the first string (8.3b5-HP) is greater than the second string (7.1).
That’s all well and good, except for this: what are we supposed to do with the -1 that StrComp returns to us? As it turns out, we’re going to execute this block of code:
If intComparison = -1 Then Wscript.Echo "String 1 is less than string 2." Wscript.Quit (1) ElseIf intComparison = 1 Then Wscript.Echo "String 1 is greater than string 2." Wscript.Quit (2) Else Wscript.Echo "The two strings are identical." Wscript.Quit (3) End If
All we’re doing here is using a set of If-Then statements to take action based on the value of intComparison (that is, based on the number returned by StrComp). Suppose intComparison is -1? That’s fine; in that case we execute these two lines of code:
Wscript.Echo "String 1 is less than string 2." Wscript.Quit (1)
In the first line we’re simply echoing back the fact that string 1 is less than string 2. (We don’t really need to do that, but when you’re testing your script this makes it easy to determine whether or not the script is working correctly.) In addition to that, we use the Quit method to terminate the script. But notice that we don’t just Quit; instead, we specify an errorlevel of 1 when quitting:
So will that really set the DOS errorlevel to 1? You bet it will. And you can verify that by typing the following command at the command prompt:
Unless you’re in a terrible slump and nothing is going right for you, you should get back the following:
Granted, that’s not much. But it’s all we really needed.
We then run a separate check to see if intComparison is equal to 1; in that case, that means that string 1 is greater than string 2, which also means that we execute these two lines of code instead:
Wscript.Echo "String 1 is greater than string 2." Wscript.Quit (2)
And what if intComparison isn’t equal to either 1 or -1? Well, in that case we assume that intComparison is equal to 0, which means that the two strings are identical:
Wscript.Echo "The two strings are identical." Wscript.Quit (3)
And that, as they say, is that.
If you aren’t a baseball fan you might have been a little … surprised … to hear that a major leaguer would wear a gold-lamé, tiger-striped thong under his uniform in an attempt to break out of the slump. Admittedly that is a little weird, but, then again, not that weird, at least not for baseball players. Needless to say, baseball players tend to be a little superstitious. For example, Kevin Rhomberg, a journeyman major leaguer back in the 80s, had a compulsive need to “touch back” anyone or anything that touched him. One time, in a minor league game, Rhomberg was tagged out by a player who was aware of this superstition. Upon tagging Rhomberg this player turned and threw the ball out of the stadium. Rhomberg, in turn, spent several hours after the game trying to track the ball down.
We can’t remember for sure if Rhomberg ever found the ball or not, but if he didn’t, well, no big deal. After all, any time he was unable to touch someone back he would simply send them a letter saying, “This counts as a touch.”
Even the Scripting Guy who writes this column is not immune to baseball superstitions. For example, back in his playing days he used to eat coleslaw every game day. Why would he eat coleslaw in every game day, especially in light of the fact that he doesn’t really like coleslaw? Because when he was 12 the Scripting Mom made him eat some coleslaw before a game. “Coleslaw is good for you,” she said. “It’ll help you get some hits.” That night the Scripting Guy who writes this column went 3-for-3; after that he began eating coleslaw before every game. This same Scripting Guy also had to walk around the umpire and catcher in order to get into the batter’s box; he could not cross in front of them. Why not? Beats us. But if it was a choice between that or wearing a gold-lamé, tiger-striped thong, well ….
Incidentally, the Scripting Editor is once again playing in the Microsoft softball league, and the Scripting Guy who writes this column has noticed that she has a few baseball-related superstitions as well. For example, if she’s playing second base and the ball is hit to her she absolutely refuses to catch the ball; instead she just lets it go by. Likewise, when she’s at bat, she’s very superstitious about hitting the ball hard; instead she just dribbles a ground ball to one of the infielders.
Maybe she needs to eat more coleslaw.
Editor’s Note: The Scripting Editor has no superstitions that keep her from fielding ground balls and getting solid base hits. Sometimes the glove and the bat seem to be a little superstitious, though. Maybe some coleslaw in the glove…? Okay, maybe not.