سؤال

The following command pipes the output of echo to findstr and tries to match a regular expression with it. I use it to check if the echoed line only consists of (one or more) digits:

echo 123 | findstr /r /c:"^[0-9][0-9]*$"

The expected output of findstr is 123, which means that the expression could be matched with this string. The output is correct when I execute the command with powershell.exe. Executing the command in cmd.exe however does not give a match. It only outputs an empty line and sets %ERRORLEVEL% to 1, which means that no match was found.
What causes the different behavior? Is there a way to make this command run correctly on cmd as well?

My OS is Windows 7 Professional, 64 Bit.

هل كانت مفيدة؟

المحلول

In Powershell the command echoes the string 123 to the pipeline and that matches your regular expression.

In cmd, your command echos 123<space> to the pipeline. The trailing space isn't allowed for in your regular expression so you don't get a match.

Try:

echo 123| findstr /r /c:"^[0-9][0-9]*$"

and it will work just fine. Or just switch entirely to Powershell and stop having to worry about the vagaries of cmd.exe.

Edit: Yes, cmd and powershell handle parameters very differently.

With cmd all programs are passed a simple text command line. The processing that cmd performs is pretty minimal: it will terminate the command at | or &, removes i/o redirection and will substitute in any variables. Also of course it identifies the command and executes it. Any argument processing is done by the command itself, so a command can choose whether spaces separate arguments or what " characters mean. Mostly commands have a fairly common interpretation of these things but they can just do their own thing with the string they were given. echo does it's own thing.

Powershell on the other hand has a complex syntax for arguments. All of the argument parsing is done by Powershell. The parsed arguments are then passed to Powershell functions or cmdlets as a sequence of .Net objects: that means you aren't limited to just passing simple strings around. If the command turns out not to be a powershell command and runs externally it will attempt to convert the objects into a string and puts quotes round any arguments that have a space. Sometimes the conversion can be a bit confusing, but it does mean that something like this:

echo (1+1)

will echo 2 in Powershell where cmd would just echo the input string.

It is worth always remembering that with Powershell you are working with objects, so for example:

PS C:\> echo Today is (get-date)
Today
is

17 April 2014 20:03:15


PS C:\> echo "Today is $(get-date)"
Today is 04/17/2014 20:03:20

In the first case echo gets 3 objects, two strings and a date. It outputs each object on a separate line (and a blank line when the type changes). In the second case it gets a single object which is a string (and unlike the cmd echo it never sees the quote marks).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top