Perl one-liner with single quote - perl

I use a Perl one-liner to create an SQL statement, but I am not able to include single quotes.
This is what I want: Take the first field and add quotes to it.
echo "a,b" | perl -F',' -lane 'print $F[0];'
'a'
I tried a few different ways, but it didn't work for me.
 
echo "a,b" | perl -F',' -lane 'print qq('$F[0]');'
[0]
 
echo "a,b" | perl -F',' -lane 'print q('$F[0]');'
[0]
Here is another interesting issue.
It is printing a single quote with the print statement, but if I assign a value to the variable and print, it's not working.
perl -lwe "print q( i'am );"
i'am
perl -lwe "$b=q( didn't ); print $b"
How can we use single and double quotes in Perl one-liners?

You can't use single quotes alone. You need to escape them correctly using '\'' This works:
$ echo "a,b" | perl -F',' -lane 'print "'\''$F[0]'\''";'
'a'

You need to learn how your shell treats quotes.
I would just use the ASCII value for ':
echo "a,b" | perl -F',' -lane 'print "$F[0]\047";'
a'
q// and qq// operators can also be useful in one-liners.

Use a variable with the octal value:
echo "a,b" | perl -F',' -lane '$sq="\047"; print "$sq$F[0]$sq";'
Also, a slight modification of your attempt #1 would work:
echo "a,b" | perl -F',' -lane "print qq{'\$F[0]'};"
That uses double quotes for the outer set and escapes the dollar sign to prevent the shell from interpreting it.

Placing the script in double quotes rather than single quotes will allow you to use single quotes inside the script without having to escape or use ANSI sequences to represent the single quote. This is likely the most effective and easily-readable solution.

Related

perl -lane change delimiter

I have one liner:
az account list -o table |perl -lane 'print $F[0] if /GS/i'
I want to change default delimiter from '\t' to '-'
Any hint how to do this?
Just wanted to stress that it is oneliner I look for ;)
Plain -a splits on any whitespace, not just tab. The -F option allows you to specify a different delimiter.
az account list -o table |
perl -laF- -ne 'print $F[0] if /GS/i'
perlrun is the manual page that tells you about Perl's command-line options. It says:
-a
turns on autosplit mode when used with a "-n" or "-p". An implicit split command to the #F array is done as the first thing inside the implicit while loop produced by the "-n" or "-p".
perl -ane 'print pop(#F), "\n";'
is equivalent to
while (<>) {
#F = split(' ');
print pop(#F), "\n";
}
An alternate delimiter may be specified using -F.
And:
-Fpattern
specifies the pattern to split on for "-a". The pattern may be surrounded by //, "", or '', otherwise it will be put in single quotes. You can't use literal whitespace or NUL characters in the pattern.
-F implicitly sets both "-a" and "-n".

Replace a string in file with new string containing $ sign in Perl

I am trying to replace string with a new string containing $(dollar) sign in a existing file.
I have used below (regex) line in my code but I am not able get the expected result. Please suggest the solution.
system("perl -pi -e \"s/length\\s+.*/length [index $pkt_len]/g if /^\\s*set_value\\s+length/\" $filename")
The way to find the solution is during debug you should print out the line of the system call and test it "by hand" if it works as expected in the shell.
My guess is that
system("perl -pi -e 's/length\\s+.*/length [index \\\$pkt_len]/g if /^\\s*set_value\\s+length/' $filename")
is a solution.
You need 7 backslashes (!):
system("echo a | perl -pe \"s/a/\\\\\\\$foo/\"");
Output:
$foo
First "echo a | perl -pe \"s/a/\\\\\\\$foo/\"" is interpreted by perl which reduces the string to echo a | perl -pe "s/a/\\\$foo/"
Then it is parsed by the shell sh to give : echo a | perl -pe s/a/\$foo/
Finally, it is parsed by perl a second time to give the output $foo.

How can I use perl one liner to split one line in to multiple using regex?

How can I split a line in to multiple lines using a Perl one-liner?
Input:
AAAA | BBBB | CCCCCCCCCCC | 19999AAA | AAA
Output:
AAAA
BBBB
CCCCCCCCCCC
19999AAA
AAA
One way is to replace the whitespace and pipe delimiter with a line break.
echo "your input" | perl -pe 's/\s*\|\s*/\n/g'
You can perform a split here and join your strings.
echo "your input" | perl -ne 'print join("\n", split /\s*\|\s*/, $_)'
Since you're asking for a one-liner, I suppose you're not trying to put this in an existing perl script, so why not use a plain shell command for this:
tr -s '| ' '[\n*]'
This replaces any sequence of characters in the first set into a newline. The peculiar syntax [\n*] makes sure this works with any POSIX-compliant tr. With GNU or BSD tr, this simpler syntax should also work:
tr -s '| ' '\n'
Pretty much the same can be done with Perl proper:
perl -pe 'tr/ |/\n/s'
Using something like one of those:
perl -pe 's/ \| /\n/g'
perl -nE 'say for split / \| /'

How to use perl one-liner as an alias

To filter non-consecutive lines of file, the below one-liner working fine:
cat filename | perl -ane 'print unless $a{$_}++'
However, when i tried to make it as an alias and do, its not working as expected
alias uniqlines " cat \!* | perl -ane 'print unless \$a{\$_}++' "
erroring out as below
a: Undefined variable.
Using tcsh shell for SunOS operating system
In bash this syntax works:
alias uniqlines="perl -ane 'print unless \$a{\$_}++' "
Here is a way that seems to work even in tcsh:
alias uniqlines 'perl -ane '"'"'print unless $a{$_}++'"'"' '
You want to use a function instead:
uniqlines(){ cat "$#" | perl -ane 'print unless $a{$_}++'; }
But this is pretty much just a fancy way of saying:
alias uniqlines=uniq

What am I doing wrong in this Perl one-liner?

I have a file that contains a lot of these
"/watch?v=VhsnHIUMQGM"
and I would like to output the letter code using a perl one-liner. So I try
perl -nle 'm/\"\/watch\?v=(.*?)\"/g' filename.txt
but it doesn't print anything.
What am I doing wrong?
The -n option processes each line but doesn't print anything out. So you need to add an explicit print if you successfully match.
perl -ne 'while ( m/\"\/watch\?v=(.+?)\"/g ) { print "$1\n" }' filename.txt
Another approach, if you're sure every line will match, is to use the -p option which prints out the value of $_ after processing, e.g.:
perl -pe 's/\"\/watch\?v=(.+?)\"/$1//' filename.txt
Your regex is fine. You're getting no output because the -n option won't print anything. It simply wraps a while (<>) { ... } loop around your program (run perl --help for brief explanations of the Perl options).
The following uses your regex, but add some printing. In list context, regexes with the /g option return all captures. Effectively, we print each capture.
perl -nle 'print for m/\"\/watch\?v=(.*?)\"/g' data.dat
You can split the string on "=" instead of matching:
perl -paF= -e '$_= #F[1]' filename.txt