PowerShell tips for bash users, part 1

PowerShellSome software testers often write shell scripts to make life a bit easier. But real power of shell lies in shell itself, in so called “oneliners” which UNIX and Linix admins (and also testers in UNIX environments which I used to be) so much love and use. When transfered to Windows environments, those guys will probably continue to use tools they are comfortable with. There are myriad of UNIX shell ports (for bash shell there is Win-bash) and emulators (Cygwin) out there to help create UNIX or Linux like environments in Windows. However, sometimes one is stuck with pure Windows…

Windows Servers are shipping lately with scripting environment called PowerShell (ex Monad AFAIR). If you use Core installation of Windows server, PowerShell is more or less the only thing you have. I will give here few quick oneliner PowerShell tips for people used to work with bash and UNIX command line in general. In this first article in a series we will be talking about: backticks, command separators, newlines, blanks, xargs, tr and cut.

Backticks, command separators and new lines

In bash, stdout output of every command is text, so commands can be executed inline and operated on its output right away:

 


$ echo "dir1 dir2" > dirs
$ for a in `cat dirs`; do mkdir $a; done

 

This will create directories dir1 and dir2 in working directory. This also illustrate how to write for loop in one line. However, even if “do” and “done” are shell keywords, not commands, semicolon (or new line) is needed for separation as if we have list of commands.

PowerShell equivalent:

 


PS> echo "dir1" "dir2" > dirs
PS> foreach ($a in cat dirs) {mkdir $a}

 

Second PowerShell line is more readable because of the use of brackets and braces and there is also no need for backticks apparently. However, note that we have to separate strings to be echoed to file to force new line. If strings are written in the same line as with ‘echo “dir1 dir2” > dirs’, mkdir (standard cmd.exe) will create one directory named “dir1 dir2.”

xargs

Xargs is one of the most powerfull UNIX commands. It is used to build and execute command lines from standard input. For example:
$ cat dirs | xargs mkdir
will use cat to take the strings (be it newline or blank character separated) from file ‘dirs’ and pass them through pipe to xargs which will then send one by one line as argument to mkdir which will then create those dirs or complain if those are existent.

PowerShell equivalent:

 

PS> cat dirs | %{mkdir $_}

 

There is no ‘xargs’ command in PS, but you can use ‘foreach ‘ loop and pass the piped variable ‘$_’ to the mkdir. Shorthand for ‘foreach’ is ‘%’. This time also only newlines will separate the strings apart. If multiple strings separated by blanks are found in same line, mkdir will create a directory with blanks in the name, while we must quote to have the same in bash:

 

$ cat dirs | sed 's|^|"|g' | sed 's|$|"|g' |xargs mkdir

 

cut

Cut is another useful UNIX command. It us used to cut sections from each line of output or file. For example:

 

$ echo 'why:me ' | cut -d ':' -f1
why

 

will print “why” because cut will cut everything behind delimeter “:”

Powershell has no simmilar cmdlet but has a neat function ‘split’ which can do the same:

 

PS> echo 'why:me' | %{$_.split(':')[0]}
why

 

but, mind the syntax. Even if it is completely understandable, it is not handy.

tr

Ever once in a while one must to replace some character of text output with another. Let say slash with backslash:

Bash:

 

$ echo 'why/not' | tr '/' '\\'

 

Powershell again has no tr command, but do has a “-replace” parameter which expects input from another PS cmdlet. Piped output is also ok:

 

PS> echo 'why/not' | %{$_ -replace '/', '\'}

 

Again mind the synthax. “-replace” used here is not the function which operates on variable, therefore there is no dot (do not confuse this with Replace function in PS). Also, seems we do not have to escape neither of slashes. However, while tr works only with characters, replace can be used on whole strings while on UNIX we would use sed or awk for string replacement.

  • First example with less PowerScript code:
    echo dir1 dir2 > dirs
    cat dirs | % {echo $_}
    or as a one-liner:
    echo dir1 dir2 | % {mkdir $_}

  • The PowerShell to match the “cut” example could be
    ‘why:me’.split(‘:’)[0]

  • And for the tr example, here’s some alternative PowerShell

    ‘why/not’.Replace(‘/’, ‘\’)

  • Thx for your comments Larry. Extensive use of pipes in examples are due to its usabilty in real world where information to be processed usualy are not just echoed.

  • It seems you are an advanced Microsoft Windows user: Can GNU Parallel http://www.gnu.org/software/parallel/ be installed on Windows? And if not: What change would be needed in GNU Parallel?

    for a in `cat dirs`; do mkdir $a; done

    can be written as:

    cat dirs | parallel mkdir

    even if dirs contain lines containing space, ‘ or “.

    GNU Parallel can do more than that. See http://www.youtube.com/watch?v=LlXDtd_pRaY

    • Thx for the tip. Seems like powerfull tool. I suppose GNU parallel can be compiled for Cygwin. Did you try?

      • GNU Parallel is written in Perl and I have just tried the most basic functionality on Cygwin. It seems to work, but is a bit slow – maybe system() is really slow in Cygwin?

        As I am not a Microsoft Windows user I will not be able to spend a lot of time getting it to work better. But design ideas and patches are always welcome at bug-parallel@gnu.org.

        A new intro video is now at http://www.youtube.com/watch?v=OpaiGYxkSuQ

  • Good job!

  • Yaro Kasear

    Sorry, but any good BASH user would be sorely disappointed in PowerShell’s meager offerings. And pretty much anyone using anything more advanced than BASH (ZSH comes to mind.) laughs at the suggestion of PS being anything useful for them.

    That’s how badly-implemented copies of software fare. If Microsoft wants to make a UNIX shell, they should go all the way and actually provide a POSIX system to go with it.

    • Well, MS decided to make Windows shell, not UNIX one ;) Thx for your comment

  • You guys are incorrect, and really should not be so difficult around the author. This site seems to be devoted to stating their very own view, which the majority of us have. I detest when persons attempt to talk poor about someone for the reason that their thoughts and opinions differs from others. Take a look at your self just before you are trying to talk about another person.

  • Yaro Kasear

    @ovca.org – He is suggesting that PowerShell would actually satisfy a BASH user’s needs. The fact that PS is absolute crap compared to an actual UNIX shell. Which PowerShell *is* trying to be, despite Banovotz’s comment to the contrary. If Microsoft wanted a Windows shell they’d simply make a glorified DOS command line. (Oh, wait… They already DID.) PowerShell was *explicitly* designed to hook UNIX admins. Too bad for Microsoft UNIX admins actually have have brains on their shoulders and see how bland PS is in comparison to the likes of BASH and especially ZSH.

    If he can’t take criticism, he really shouldn’t be BLOGGING IN THE PUBLIC SPHERE. Because if you blog like an idiot, people are within their rights to CALL him one.

    This blogger’s an idiot.

    Have a nice day.

    • Thx for fud. But why not read the text first?

  • Honeymonster

    I wish you would try to learn a little more about PowerShell before trying to teach it like this.

    The bash script:

    echo "dir1 dir2" > dirs
    for a in `cat dirs`; do mkdir $a; done

    The PowerShell equivalent

    echo "dir1 dir2" > dirs
    gc dirs | mkdir -path {$_}

    Explanation: Pipe the lines from “dirs” into invocations of mkdir, on each invocation bind the “path” parameter to the $_ expression. $_ represents piped string value.

    So in effect PS has a built-in “xargs” functionality – only much more powerful.

    As for your “split” example: You are actually using the string type’s “Split” method (a .NET method). PowerShell does have an actual -split operator as well as built-in regular expression matcher for very advanced cases. Or you could look up ConvertFrom-Csv or Import-Csv which (despite the name) may use other delimiters than commas. For instance, to parse a Linux passwd and format it nicely in a table file you could use this simple command:
    Import-Csv passwd -del : -head account,password,UID,GID,GECOS,directory,shell | ft
    If you wanted to list only the home directories you could use Import-Csv passwd -del : -head account,password,UID,GID,GECOS,directory,shell | select directory

    Instead of echo 'why/not' | %{$_ -replace '/', '\'}
    you should do the simpler (and easier to read)
    (echo 'why/not') -replace '/', '\'

  • Hugh

    Great article. I must disagree with the commenter above. I *know* that Powershell has an underlying object model and lots of functionality (and its own syntax). But I don’t have enough need for that right now to spare the bandwidth on a platform-specific tool.

    I do more unix than windows work these days and usually use cygwin bash, but need need to get a few things done right now on one dev box. This article is very handy for me.

  • svyelunite

    Thanks banovotz and Honeymonster for both your post and comment. They both helped me a great deal.

    Just one little issue on Honeymonster’s comment, if you don’t put double quotation marks on the delimiter “;” it won’t work.

    Thanks again.

  • Pingback: Leaving ones Comfort Zone (draft). | TDI Web Log()

  • Made from reissued prints and patterns from the Vans archives with the original Van Doren heel tab, the Era, Vans classic low top lace-up skate shoe, has a durable double-stitched canvas upper with checkerboard fabric detail, printed heritage Vans sidewal Vans Shoes,Cheap Vans,Vans For Sale,Vans Shoes Outlet,Custom Vans Shoes,vans lindero grey seafoam evo,vans era guateCustom Vans Shoes Vans Van Doren Era Shoes-(Van Doren) Black/Checker-VVHQ8XJMade from reissued prints and patterns from the Vans archives with the original Van Doren heel tab, the Era, Vans classic low top lace-up skate shoe, has a durable double-stitched canvas upper with checkerboard fabric detail, printed heritage Vans sidewalMade from reissued prints and patterns from the Vans archives with the original Van Doren heel tab, the Era, Vans classic low top lace-up skate shoe, has a durable double-stitched canvas upper with checkerboard fabric detail, printed heritage Vans sidewal

  • I read a lot of interesting articles here. Probably you
    spend a lot of time writing, i know how to save you
    a lot of work, there is an online tool that creates readable,
    google friendly posts in minutes, just type in google – laranitas free content source

  • Pingback: Vanessa Smith()

  • Pingback: free download google()

  • Pingback: download firefox()

  • Pingback: java runtime()

  • Pingback: skype download()

  • Pingback: zakład szklarski piotrków trybunalski()

  • Pingback: xmt85c4wx5ctwxw3tcerthve56()

  • Pingback: http://falschgeldkaufen.blogspot.com/2017/01/wo-kann-ich-falschgeld-kaufen.html()