Why is sed not extracting value? - regex

When I run my regex with sed
echo "abc-def-stg" | sed -e '/(\w*$)/g'
on regexr.com it works with no problems, but when I try to extract the value stg using said it does not work.
Can anyone explain why?

sed is used to replace strings. You are trying to extract.
Use (as John1024 said)
echo "abc-def-stg" | sed '/.*-//'
It will remove all up to and including the last hyphen. Or
echo "abc-def-stg" | grep -oE '[^-]+$'
It will extract all characters other than a hyphen at the end of the string.

Related

Regex - sed to extract word between patterns

I'm trying to extract the word hello from ENC(hello) using sed.
I've tried the following but so far no joy:
property="ENC(hello)" && echo "$property" | sed 's/(?<=^ENC\()(.*)(?=\))/\1/'
Can you advise what am doing wrong?
property="ENC(hello)" && echo "$property" | sed -e 's/ENC(\(.*\))/\1/'
the problem is that sed seems to not support the "lazy" match but to be always greedy, so if in one line you have
ENC(hello) ENC(world)
such regex won't help

Printing only text from group

I have working example of substitution in online regex tester https://regex101.com/r/3FKdLL/1 and I want to use it as a substitution in sed editor.
echo "repo-2019-12-31-14-30-11.gz" | sed -r 's/^([\w-]+)-\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}.gz$.*/\1/p'
It always prints whole string: repo-2019-12-31-14-30-11.gz, but not matched group [\w-]+.
I expect to get only text from group which is repo string in this example.
Try this:
echo "repo-2019-12-31-14-30-11.gz" |
sed -rn 's/^([A-Za-z]+)-[[:alnum:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{2}-[[:digit:]]{2}.gz.*$/\1/p'
Explanations:
\w will work (not [\w] wich matches either backslash or w), but you should use [[:alnum:]] which is POSIX
For sed, \d isn't a regex class, but an escaped character representing a non-printable character
Add -n to mute sed, with /p to explicitly print matched lines
Additionaly, you could refactor your regex by removing duplication:
echo "repo-2019-12-31-14-30-11.gz" |
sed -rn 's/^([[:alnum:]]+)-[[:digit:]]{4}(-[[:digit:]]{2}){5}.gz.*$/\1/p'
Looks like a job for GNU grep :
echo "repo-2019-12-31-14-30-11.gz" | grep -oP '^\K[[:alpha:]-]+'
Displays :
repo-
On this example :
echo "repo-repo-2019-12-31-14-30-11.gz" | grep -oP '^\K[[:alpha:]-]+'
Displays :
repo-repo-
Which I think is what you want because you tried with [\w-]+ on your regex.
If I'm wrong, just replace the grep command with : grep -oP '^\K\w+'

Extracting Substring from String with Multiple Special Characters Using Sed

I have a text file with a line that reads:
<div id="page_footer"><div><? print('Any phrase's characters can go here!'); ?></div></div>
And I'm wanting to use sed or awk to extract the substring above between the single quotes so it just prints ...
Any phrase's characters can go here!
I want the phrase to be delimited as I have above, starting after the single quote and ending at the single-quote immediately followed by a parenthesis and then semicolon. The following sed command with a capture group doesn't seem to be working for me. Suggestions?
sed '/^<div id="page_footer"><div><? print(\'\(.\+\)\');/ s//\1/p' /home/foobar/testfile.txt
Incorrect would be using cut like
grep "page_footer" /home/foobar/testfile.txt | cut -d "'" -f2
It will go wrong with single quotes inside the string. Counting the number of single quotes first will change this from a simple to an over-complicated solution.
A solution with sed is better: remove everything until the first single quote and everything after the last one. A single quote in the string becomes messy when you first close the sed parameter with a single quote, escape the single quote and open a sed string again:
grep page_footer /home/foobar/testfile.txt | sed -e 's/[^'\'']*//' -e 's/[^'\'']*$//'
And this is not the full solution, you want to remove the first/last quotes as well:
grep page_footer /home/foobar/testfile.txt | sed -e 's/[^'\'']*'\''//' -e 's/'\''[^'\'']*$//'
Writing the sed parameters in double-quoted strings and using the . wildcard for matching the single quote will make the line shorter:
grep page_footer /home/foobar/testfile.txt | sed -e "s/^[^\']*.//" -e "s/.[^\']*$//"
Using advanced grep (such as in Linux), this might be what you are looking for
grep -Po "(?<=').*?(?='\);)"

Getting defined substring with help of sed or egrep

Everyone!!
I want to get specific substring from stdout of command.
stdout:
{"response":
{"id":"110200dev1","success":"true","token":"09ad7cc7da1db13334281b84f2a8fa54"},"success":"true"}
I need to get a hex string after token without quotation marks, the length of hex string is 32 letters.I suppose it can be done by sed or egrep. I don't want to use awk here. Because the stdout is being changed very often.
This is an alternate gnu-awk solution when grep -P isn't available:
awk -F: '{gsub(/"/, "")} NF==2&&$1=="token"{print $2}' RS='[{},]' <<< "$string"
09ad7cc7da1db13334281b84f2a8fa54
grep's nature is extracting things:
grep -Po '"token":"\K[^"]+'
-P option interprets the pattern as a Perl regular expression.
-o option shows only the matching part that matches the pattern.
\K throws away everything that it has matched up to that point.
Or an option using sed...
sed 's/.*"token":"\([^"]*\)".*/\1/'
With sed:
your-command | sed 's/.*"token":"\([^"]*\)".*/\1/'
YourStreamOrFile | sed -n 's/.*"token":"\([a-f0-9]\{32\}\)".*/\1/p'
doesn not return a full string if not corresponding

Sed substitute input by first matching argument

I'm trying to get some sed command to work without success...
echo -e "This.Is.a.Test.V03.r501.dump" | sed "s/^\(\w+(\.\w+)*\)\.V[0-9]{2}.*$/\1/g"
Basically, I want to match and return This.Is.a.Test while this \.V[0-9]{2} is fixed, but instead it returns the whole input string.
Any help is appreciated, thanks in advance!
\w matches alphanumerics, you are looking to capture only alphabets, so replace \w with [:alpha:]. Additionally {2} needs to be replaced with \{2\}. The following works with GNU sed
echo -e "This.Is.a.Test.V03.r501.dump" |
sed "s/^\([[:alpha:].]\+\)\.V[0-9]\{2\}.*$/\1/g"
This.Is.a.Test
Try this.
echo -e "This.Is.a.Test.V03.r501.dump" | sed -e "s/\(.*\)\.V[0-9]*.*/\1/"
Another way with sed
sed -r 's/^(([^.]+.){3})([^.]+).*/\1\3/'
Are you looking for this?
One way is to use awk
$ echo "This.Is.a.Test.V03.r501.dump" | awk -F'.' 'BEGIN{OFS=FS}{NF=4}1'
This.Is.a.Test