If you want to start a Perl script/program from PowerShell, you will need to manually specify the interpreter by prepending "perl " in front of the script (like "perl .\myscript.pl"). Of course, you need a full path to perl.exe unless it's in a directory included in the %PATH% environment variable (accessible as $env:PATH in PowerShell).
If you just type ".\perlscript.pl", it will pop open a cmd.exe window that often immediately closes, depending on the nature of the script you're running. Some are made interactive or have GUIs - and should work as expected, although they will close abruptly once they're done, and leave you unable to inspect output that might have been there. You want "perl .\myscript.pl".In cmd.exe, you can just use the script name followed by its arguments without the need to prepend "perl " - given that .pl files are correctly associated with a Perl interpreter (c:\perl\bin\perl.exe or similar).
The short version of this article is: For PowerShell-called Perl one-liners, use single quotes and Perl's handy qq() and q() operators for "stringification" between the single quotes. This significantly helps you avoid quoting issues.
E:\>echo abc123def | perl -nwe "print /(\d+)/" 123 E:\>echo abc123def | perl -nwe 'print /(\d+)/' Can't find string terminator "'" anywhere before EOF at -e line 1. E:\>
To print or use literal double quotes inside the Perl one-liner, you will need to escape them:
C:\>perl -le "print 'something \"with\" quotes';" something "with" quotes
This is also quirky, because I accidentally left out the last quote, and it didn't complain. cmd.exe seems to have a vague concept of quoting and strings. As seen here:
C:\>perl -le "print 'something \"with\" quotes'; something "with" quotes
Your safest bet will be to quote correctly, of course. You can also leave out the semicolon if you only have a single statement.
If there are no conflicting meta characters or "PowerShell syntax" in the Perl one-liner, both will work seemingly equivalently, as demonstrated here:
PS C:\> 'abc123def' | perl -nwle 'print /(\d+)/' 123 PS C:\> 'abc123def' | perl -nwle "print /(\d+)/" 123
Notice how I added the "-l" option, which basically says "append a newline to everything you print()". In cmd.exe you don't really need it because the shell is designed to always present you with a prompt starting on a new line, so you get the last newline for free. On Linux, and in PowerShell, you need to be aware of this issue and add newlines unless you want output like this:
PS C:\> 'abc123def' | perl -nwe 'print /(\d+)/' 123PS C:\>
Without the "-l" option, you would have to do something like this:
PS C:\> 'abc123def' | perl -nwe 'print qq($1\n) if /(\d+)/' 123
Notice how I use qq() rather than double quotes. This is because double quotes apparently can confuse the PowerShell interpreter (sometimes it seems to work). Escaped single quotes don't seem to work too well either, so use q() for that. To sum it up, again: For PowerShell-called Perl one-liners, use single quotes and Perl's handy qq() and q() operators for "stringification" between the single quotes. This significantly helps you avoid quoting issues.
Although escaping the single quotes for PowerShell's sake, by doubling them up, can also work:PS C:\> "foo","bar",'baz' | perl -nwle 'print qq(''$_'');' 'foo' 'bar' 'baz'
To use double quotes literally in Perl, you need to escape them (in most cases, and always if they're unbalanced, is my current theory) with a backslash, not a backtick. This is a bit confusing:
PS C:\> '"Hello, ' | perl -pwe 's/(\"Hello, )/${1}world\"/' "Hello, world"
With Perl 5.10 came ''say()'', which is just like ''print()'', but automatically appends a newline (type "perldoc -f say" at the prompt to read more about it), but you might need to enable it like this, so it's about as clunky as print/qq - and the parameter "-l" is probably still better. Using ''say()'', it looks like this:
PS E:\> 'abc123def' | perl -Mfeature=say -nwe 'say /(\d+)/' 123
PS C:\> 1..3 | perl -nle 'print qq(#$_#)' #1# #2# #3#
If you were to try with double quotes, it would fail, but I do not fully understand what's going on, since you get just the pipeline output without the surrounding parts. I think somehow the string is being parsed by PowerShell before Perl does its thing with it. If you escape the double quotes with backslashes, it will also work:
PS C:\> 1..3 | perl -nle 'print "#$_#";' 1 2 3 PS C:\> 1..3 | perl -nle 'print \"#$_#\";' #1# #2# #3#
If you try using double quotes around the expression, and then escaping the inner double quotes with the PowerShell escape character, you will see the broken behaviour again:
PS C:\> 1..3 | perl -nle "print `"#$_#`";" 1 2 3
If you try to escape the inner double quotes with backslashes like demonstrated below, you will see a different type of unwanted behaviour:
PS C:\> 1..3 | perl -nle "print \"#$_#\";" Can't find string terminator '"' anywhere before EOF at -e line 1.
It also seems like "#" isn't a random character, because:
PS C:\> 1..3 | perl -nle "print `"foo: $_`";" syntax error at -e line 1, near "foo:" Execution of -e aborted due to compilation errors.
I haven't been able to make it work with double quotes both places and getting the escaping right, but if you use qq and escape "$_" for PowerShell's sake, you can work around it, but I stand by the "best practices" I outline at the top of this Perl one-liner quoting in PowerShell section.
PS C:\> 1..3 | perl -nle "print qq(foo: `$_)" foo: 1 foo: 2 foo: 3
PS C:\> $PerlCode = 'print join q(, ), q(a)..q(z)' PS C:\> perl -wle $PerlCode a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z PS C:\>Powershell Perl Windows All Categories
Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.