I am trying to replace part of the string, but can not find a proper regex for sed to execute it properly.
I have a string
/abc/foo/../bar
And I would like to achive the following result:
/abc/bar
I have tried to do it using this command:
echo $string | sed 's/\/[^:-]*\..\//\//'
But as result I am getting just /bar
.
I understand that I must use group, but I just do not get it. Could you, please, help me to find out this group that could be used?
CodePudding user response:
You can use
#!/bin/bash
string='/abc/foo/../bar'
sed -nE 's~^(/[^/]*)(/.*)?/\.\.(/[^/]*).*~\1\3~p' <<< "$string"
See the online demo. Details:
-n
- suppresses default line outputE
- enables POSIX ERE regex syntax^
- start of string(/[^/]*)
- Group 1: a/
and then zero or more chars other than/
(/.*)?
- an optional group 2: a/
and then any text/\.\.
- a/..
fixed string(/[^/]*)
- Group 3: a/
and then zero or more chars other than/
.*
- the rest of the string.\1\3
replaces the match with Group 1 and 3 values concatenatedp
only prints the result of successful substitution.
CodePudding user response:
You can use a capture group for the first part and then match until the last /
to remove.
As you are using /
to match in the pattern, you can opt for a different delimiter.
#!/bin/bash
string="/abc/foo/../bar"
sed 's~\(/[^/]*/\)[^:-]*/~\1~' <<< "$string"
The pattern in parts:
\(
Capture group 1/[^/]*/
Match from the first till the second/
with any char other than/
in between
\)
Close group 1[^:-]*/
Match optional chars other than:
and-
then match/
Output
/abc/bar
CodePudding user response:
Using sed
$ sed 's#^\(/[^/]*\)/.*\(/\)#\1\2#' input_file
/abc/bar
or
$ sed 's#[^/]*/[^/]*/##2' input_file
/abc/bar
CodePudding user response:
Using awk
string='/abc/foo/../bar'
awk -F/ '{print "/"$2"/"$NF}' <<< "$string"
#or
awk -F/ 'BEGIN{OFS=FS}{print $1,$2,$NF}' <<< "$string"
/abc/bar
Using bash
string='/abc/foo/../bar'
echo "${string%%/${string#*/*/}}/${string##*/}"
/abc/bar