A correction I have to make regarding the Powershell and wildcards. The bash shell is still better though.

I need to correct what I said in this posting: http://www.securitronlinux.com/bejiitaswrath/bash-shell-is-better-than-powershell-and-discussion-of-the-linux-desktop-versus-windows/ and also this one. regarding the Powershell and its handling of certain constructs that I mentioned in this posting: http://www.securitronlinux.com/bejiitaswrath/windows-powershell-not-as-good-as-bash-shell-and-other-thoughts/. It turns out that the Powershell does support this after all as shown in this sample below.

PS C:\Users\Homer\Documents> ls STRIFE[0-9].wad

    Directory: C:\Users\Homer\Documents

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        23/05/1996     18:03   28377364 STRIFE1.WAD

This is how you perform a search as if you were using grep. This does actually work quite well in Windows but Linux has the advantage of greater security and more reliability than Windows.

PS C:\Users\Homer\Documents> ls | findstr "STRI*[0-9]*"
-a---        23/05/1996     18:03   28377364 STRIFE1.WAD

This construct will not work on Powershell though. This will convert the content of a shell variable into uppercase.

john@adeptus-mechanicus ~/Documents $ echo -e ${LOGNAME^^}
GORDON

There are some awesome tricks that you can use with the bash shell that do not work with Powershell. There are a few sample commands here: http://www.securitronlinux.com/bejiitaswrath/cispa-bill-still-a-threat-and-awesome-linux-shell-tricks/. The problem with the Powershell is that the commands are longer to type than the UNIX equivalents. They need to be simplified a bit, and add some more functionality like awk and gawk. Take the command below as a example of how easy it is to find and delete files on a Linux filesystem.

john@adeptus-mechanicus ~/Documents $ find /home/$LOGNAME/Documents  -name "*.o" -delete

In Powershell, you would have to type this, which is far more complex and confusing.

get-childitem c:\ -include *.TMN -recurse | foreach ($_) {remove-item $_.fullname}

So the bash shell still wins over the Powershell command line.

3 Comments

  • Posted February 1, 2013 at 8:24 AM | Permalink

    1st – why would you use findstr in PowerShell?
    2nd: Turning any string variable to uppercase is simplest thing in the world when you try it in PowerShell. You do: $logname.ToUpper() – if you do not like to type, you can tab-complete both variable name, and the name of the method.
    3rd: your translation from ‘find’ to ps way is (almost) as verbose and as slow as it can get. How about fair comparison:
    ls C:\ -r *.tmn | rm
    Sure, I can get verbose and use full cmdlet names (and tab-complete parameters if I want to), but if I want to be brief – I can. Both ls and rm are aliases defined by default. I don’t have to worry about shortening parameter, because I have to specify only part of it, long enough to disambiguate it from other parameters that exist on a given command.
    Re awk and sed – won’t event start to explain. Parsing text is fine if you have no other option. Luckily, 99/100 cases in Windows is about objects, where awk print | xargs is last think I would think of.

  • powersheller
    Posted February 16, 2013 at 7:38 AM | Permalink

    Still wrong, I see

    Bash:
    echo -e ${LOGNAME^^}

    PowerShell:
    $LOGNAME.ToUpper()

    PowerShell more to the point and more readable. Instead of stupid modifiers on parameter references which doesn’t compose, PowerShell uses proper composable functions.

    Bash:
    find /home/$LOGNAME/Documents -name "*.o" -delete

    PowerShell:
    ls c:\ *.o -r | rm

    PowerShell succint, short and much more composable. Instead of the *find* function also being able to delete/remove items (why does it do that when there’s a separate command for that?) PowerShell elevates the piping to the next level: Just compose with the rm cmdlet.

  • honeymonster
    Posted February 17, 2013 at 1:12 AM | Permalink

    Your example piping output ls through findstr demonstrates that you have not understood PowerShell *at* *all*.

    Firstly, PowerShells ls command accepts wildcard expressions directly, so instead of passing the output through some filter you can just filter directly using

    ls STRI*[0-9]

    Secondly, if you want to filter on other properties YOU DO NOT use and old findstr text-only command. This is where your ignorance shows and why you really should not comment on “which is better”. You are just embarrassing yourself. When you want to filter in PowerShell you use the Filter-Object cmdlet – which has an alias ? (a single questionmark).

    The problem is that you apply a Unix/Linux mindset to PowerShell. To you everything must be text, because that’s how it is in Unix shells. Not so in PowerShell, where everything is an *object* and text is just one possible object type (a string). If you pass output from a cmdlet (objects) through an old-style external tool, PowerShell *will* convert the objects to text. But you are much better off just working with objects. But if you are too set in a limited Unix mindset, that will be really hard for you.

    I suggest you read up on PowerShell and do some more experiments. Stay away from making sweeping comparisons until you are qualified to do so.

Post a Comment

Your email is kept private. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>