How to check for | in doing substitution in Perl - regex

I have a string with the following data in it
"email#domain.com | firstname | lastname"
I want to replace | lastname with a different value. If I use s/ to do a substitution, what do i need to do to the | to get it to recognize. If I do
$foo =~ s/ lastname/fillertext/;
it works fine. but if I do
$foo =~ s/ | lastname/fillertext/;
it doesn't work. I tried to do - \|/ lastname, "| lastname", '| lastname'.

| has a special meaning in a regular expression; if you want to match a literal |, you just need to escape it:
$foo =~ s/ \| lastname/fillertext/;

Related

How to add \ in a string before a special character

I have a string: 816788[20].
I want to add \ before [ and ] characters.
So the correct result shoud be:
816788\[20\]
The script code is:
str="816788[20]"
newStr=`echo $str | sed 's/\[/\\\[/' `
echo $newStr
But unlucky, It is fail. I have tried:
newStr=`echo $str | sed 's/\[/\"\"\[/' `
and
newStr=`echo $str | sed 's/\[/\"\["/' `
there are all wrong, Who can help me?
You may use
sed 's/[][]/\\&/g'
See the online demo:
str="816788[20]"
newStr=$(sed 's/[][]/\\&/g' <<< "$str")
echo $newStr
# => 816788\[20\]
Details
[][] matches either [ or ]
\\ - in the replacement part, inserts \ (if you use a single \, it will escape & placeholder and it will be treated as a literal & char)
& - the placeholder for the whole match
g - replaces all occurrences.
You mean something like this:
sed 's|\[|\\[|;s|\]|\\]|'
example
echo "816788[20]" | sed 's|\[|\\[|;s|\]|\\]|'
output
816788\[20\]

Powershell capture multiple values?

The following code returns only one match.
$s = 'x.a,
x.b,
x.c
'
$s -match 'x\.(.*?)[,$]'
$Matches.Count # return 2
$Matches[1] # returns a only
Excepted to return a, b, c.
The -match operator only finds the first match. The -AllMatches with Select-String will fetch all matches in the input. Also, [,$] matches a , or $ literal chars, the $ is not a string/line end metacharacter.
A possible solution may look like
Select-String 'x\.([^,]+)' -input $s -AllMatches | Foreach {$_.Matches} | Foreach-Object {$_.Groups[1].Value}
The pattern is x\.([^,]+), it matches x. and then captures into Group 1 any one or more chars other than ,.

How do I form the correct regular expression to capture everything before parentheses?

current I have a set strings that are of the format
customName(path/to/the/relevant/directory|file.ext#FileRefrence_12345)
From this I could like to extract customName, the characters before the first parentheses, using sed.
My best guesses so far are:
echo $s | sed 's/([^(])+\(.*\)/\1/g'
echo $s | sed 's/([^\(])+\(.*\)/\1/g'
However, using these I get the error:
sed: -e expression #1, char 21: Unmatched ( or \(
So how do I form the correct regular expression? and why is it relevant that I do not have a matched \( is it is just an escaped character for my expression, not a character used for formatting?
you could substitute everything after the opening parenthesis, like this (note that parentheses by default do not need to be escaped in sed)
echo 'customName(path/to/the/relevant/directory|file.ext#FileRefrence_12345)' |
sed -e 's/(.*//'
grep
kent$ echo "customName(blah)"|grep -o '^[^(]*'
customName
sed
kent$ echo "customName(blah)"|sed 's/(.*//'
customName
note I changed the stuff between the brackets.
Different options:
$ echo $s | sed 's/(.*//' #sed (everything before "(")
customName
$ echo $s | cut -d"(" -f1 #cut (delimiter is "(", print 1st block)
customName
$ echo $s | awk -F"(" '{print $1}' #awk (field separator is "(", print 1st)
customName
$ echo ${s%(*} #bash command substitution
customName

How to use variable in regex?

How do I replace regex with $var in this command?
echo "$many_lines" | sed -n '/regex/{g;1!p;};h'
$var could look like fs2#auto-17.
The sed command will output the line immediately before a regex, but not the line containing the regex.
If all this can be done easier with a Perl one-liner, then it is fine with me.
It is not beautiful, but this gives me the previous line to $var which is want I wanted.
echo "$many_lines" | grep -B1 "$var" | grep -v "$var"
In Perl regexes, you can interpolate variable contents into regexes like /$foo/. However, the contents will be interpreted as a pattern. If you want to match the literal content of $foo, you have to escape the metacharacters: $safe = quotemeta $foo; /$safe/. This can be shortended to /\Q$foo\E/, which is what you usually want. A trailing \E is optional.
I don't know if the sed regex engine has a similar feature.
A Perl one-liner: perl -ne'$var = "..."; print $p if /\Q$var/; $p=$_'
Use double quotes instead of single quotes to allow variable expansion:
echo $many_lines | sed -n "/$var/"'{g;1!p;};h'
Since you are looking for a line before the regex, with a single one liner it will not be that trivial and beautiful, but here is how I will do it (Using Perl only):
echo "$many_lines" | perl -nle 'print $. if /\Q$var/' | while read line_no; do
export line_no
echo $many_lines | perl -nle 'print if $. - 1 == $ENV{line_no}'
done
or if you want to do in one line
echo "$many_lines" | perl -nle 'BEGIN {my $content = ""; } $content .= $_; END { while ($content =~ m#([^\n]+)\n[^\n]+\Q$var#gosm) { print $1 }}'
Or this one, should definitely match:
echo "$many_lines" | perl -nle 'BEGIN {my #contents; } push #contents, $_; if ($contents[-1] =~ m#\Q$var#o)') { print $contents[-2] if defined $contents[-2]; }
Or you can use here-documents too, if you don't want to escape the double quotes!
In Perl it looks like this:
$heredoc = <<HEREDOC;
here is your text and $var is your parameter
HEREDOC
Its important to end the heredoc with the same string you began, in my example its "HEREDOC" in a new line!

how to replace a string inside perl regex

Is there a way to replace characters from inside the regex?
like so:
find x | xargs perl -pi -e 's/(as dasd asd)/replace(" ","",$1)/'
From OP's comment
code find x | xargs perl -pi -e 's/work_search=1\/ttype=2\/tag=(.*?)">(.*?)<\/a>/work\/\L$1\E\" rel=\"follow\">$2<\/a>/g'
in this case i want $1's spaces be replaced with _
You can use a nested substitution:
$ echo 'foo bar baz' | perl -wpE's/(\w+ \w+ \w+)/ $1 =~ s# ##gr /e'
foobarbaz
Note that the /r modifier requires perl v5.14. For earlier versions, use:
$ echo 'foo bar baz' | perl -wpE's/(\w+ \w+ \w+)/my $x=$1; $x=~s# ##g; $x/e'
foobarbaz
Note also that you need to use a different delimiter for the inner substitution. I used #, as you can see.
As far as I understand, you want to remove the spaces. Is it correct?
You can do:
s/(as) (dasd) (asd)/$1$2$3/