How does Getopt::Std handle spaces in arguments on the command line? - perl

I've been playing around with the Getopt::Std module and was wondering about arguments taking spaces.
I have this code atm: getopts('dp:h', \%options);
The problem is, that if the argument following the p flag contains a space, getopts stops processing the list right when it hits the space. Is there a way I can allow spaces in the arguments without having to wrap the arguments following the flag in quotes (-p "something something")?
I'm fine with quotes. I'm just curious. Thanks guys!

Take a look here, someone did a lot of experimenting ..
and this page indicates that Double Quotes " char(34) will work, if you have spaces embedded, thus implying that there is no other way ..

Related

Single quotes in a variable name in Perl?

I was writing some Perl code in vim and accidentally typed a single quote character in a variable name and noticed that it highlighted it in a different color than normal single quoted strings.
I thought that was odd, so I wrote a small test program (shown above) and tried to run it to see how Perl would handle it and I got this error:
"my" variable $var::with::apostrophes can't be in a package
What exactly is going on here? Are there situations where single quotes in variable names are actually valid? If so, what meaning do single quotes have when used in this context?
The single quote is the namespace separator used in Perl 4, replaced by the double colon :: in Perl 5. Because Perl is mostly backwards compatible, this still works. It's great for golfing, but not much else.
Here's an article about it on perl.com that doesn't explain it.

How to match \n\n using perl one liner?

My Sample file:
As I Come Into Your Presence
Key: F
1 As I come into Your presence
Past the gates of praise
Into Your sanctuary
Till we are standing face to face
And look upon Your countenance
I see the fullness of Your glory
And I can only bow down and say
Chorus:
Your awesome in this place
Mighty God
You are awesome in this place
Abba Father
You are worthy of all praise
To You our lives we raise
You are awesome in this place
Mighty God
<--- Empty line here
<--- Empty line here
I wrote this perl one-liner to get <i></i> tags around the entire chorus block:
perl -p0e "s#Chorus:(.*?)\n\n#<i>Chorus:$1</i>#gsm" file
The result:
As I Come Into Your Presence
Key: F
1 As I come into Your presence
Past the gates of praise
Into Your sanctuary
Till we are standing face to face
And look upon Your countenance
I see the fullness of Your glory
And I can only bow down and say
<i>Chorus:</i>%
I can't get the desired result where the </i> tag would be printed after the entire chorus after the Mighty God.
Where is the error? How can I achieve this?
Your solution would work if you just put it in single quotes instead of double quotes. You should pretty much always use single quotes for one-liners from the shell, no matter what language/interpreter you're running, to keep shell interpolation from messing things up.
In your code:
perl -p0e "s#Chorus:(.*?)\n\n#<i>Chorus:$1</i>#gsm" file
The $1 is being expanded by the shell before it ever gets to Perl, so Perl sees this:
perl -p0e "s#Chorus:(.*?)\n\n#<i>Chorus:</i>#gsm" file
and happily deletes your chorus. If you use single quotes instead:
perl -p0e 's#Chorus:(.*?)\n\n#<i>Chorus:$1</i>#gsm' file
it will work as intended.
Note, however, that the -0 means any NUL characters that creep into the input will still cause Perl to split it into multiple records at that point. A more correct solution would be to use -0777 instead, which tells Perl that no value should split the input; it is treated as a single record no matter what data it contains.
perl -p0777e 's#Chorus:(.*?)\n\n#<i>Chorus:$1</i>#gsm' file
escape the $
perl -p0777e "s#Chorus:(.*?)\n\n#<i>Chorus:\$1</i>#gsm" file.
also as #Kenney mention in the comment:
Use single quotes on the commandline to wrap perl expressions otherwise the shell expansion will kick in.

How to understand this perl multi-line writing command

I am trying to understand the perl commands below:
$my = << EOU;
This is an example.
Example too.
EOU
What is the name of this way? Could somebody can explain more about this "multi-line writing" command?
Essentially the syntax is allowing you to put anything unique as a marker so that it won't conflict with your contents. You can do this:
$my = <<ABCDEFG;
This is an example.
Example too.
BLAH
ABCDEFG
Everything between "This.." and "BLAH" will be assigned to the variable. Note that you shouldn't have a space after the << symbols otherwise you will get a syntax error. It helps avoid adding CR characters, or append (.) everywhere, and useful when passing data into another application (eg. ftp session). Here Documents is the correct term for this.
Everything between <<EOU and EOU is a multi-line, non-escapable, string. It's nothing fancy, think of them as start and end quote marks with nothing inside requiring escapes to be literally what you typed...

How do I ignore escape characters in command line arguments?

Consider a simple F# console application that echoes the command line arguments passed to it, one command per line:
[<EntryPoint>]
let main argv =
argv |> Array.iter (printfn "%s")
0
If I pass this program a directory path with a trailing slash, it treats the slash as an escape character producing unexpected results:
> app.exe "c:\some path\" "c:\another path"
c:\some path" c:\another
path
How can I retrieve the command line arguments without interpreting a slash as an escape character?
System.Environment.CommandLine gives you access to the complete unescaped command line, and you are free to process that however you like.
But unless you plan to implement a full-blown parser in your app, this is not going to be a reliable approach, and it's unlikely you will be able to reliably handle all of the byzantine escaping rules implemented by all of the various shells your app might have been invoked in. e.g. cmd.exe escapes things differently from powershell.exe, which is in turn different from Cygwin, etc etc.
A better choice is to simply take argv as-is, validate it as you see fit (e.g. File.Exists(argv.[0]) or whatever), and bail out with a helpful error message if the user messed something up.

Translating DOS batch file to PowerShell

I am trying to translate a .bat file to PowerShell and having trouble with understanding what a few snippets of code is doing:
set MY_VARIABLE = "some\path\here"
"!MY_VARIABLE:\=/!"
What is line 2 above doing? Specially, I dont understand what the :\=/ is doing since I have seen the variable else where in the code being referenced like !MY_VARIABLE!.
The other point of confusion is the below code.
set SOME_VARIABLE=!SOME_ARGUMENTS:\=\\!
set SOME_VARIABLE=!SOME_ARGUMENTS:"=\"!
Also, can you tell me what is going on in lines 3 and 4 above as well?
What would the below variables translate into PowerShell as well?
set TN0=%~n0
set TDP0=%~dp0
set STAR=%*
Any help on this is much appreciated. Thanks.
The !var:find=replace! is string substitution for a variable that is delay-expanded.
http://www.robvanderwoude.com/ntset.php#StrSubst
When you use ! instead of % for a variable, you want DOS to do the variable replacement at execution time (which is probably what you think it does with %, but it doesn't). With %, the variable is substituted at the point that the command is parsed (before it's run) -- so if the variable changes as part of the command, it won't be seen. I think some switch to using ! all of the time, because it gives "normal" behavior.
You can read more about delayed expansion here
http://www.robvanderwoude.com/ntset.php#DelayedExpansion
The first two set variableName= commands use modifiers to expand on the name of the batch file, represented as %0.
%~n0 expands it to a file name, and
%~dp0 expands it to include a drive letter and path.
The final one, %*, represents all arguments passed to the batch file.
Additional information can be found in answers here or here.
Exclamation points (!) i n DOS batch files reference the intermediate value, useful if you are in a for-loop. If you were to use a % instead (in a loop), it would return the same value over and over.
Lines 3 and 4 are setting "SOME_VARIABLE" to the intermediate value of "SOME_ARGUMENTS:\=\" and SOME_ARGUMENTS:"=\", respectively. Again, I'm guessing that these lines are from a loop.
As for the variable assignments, Powershell variable assignments work like this:
$myVariable = "my string"
~dp0 (in DOS batch) translates into the path (with drive letter) of the current bat file. You can get that in Powershell by doing a "get-location".
Why someone would need to set a variable for STAR(*) is beyond me, so I'm assuming there was some encoding issue or other reason that they couldn't just use an asterisk.
~n0 I'm not sure about; maybe someone else knows what that one is.