LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   sed remove string until final match (https://www.linuxquestions.org/questions/linux-newbie-8/sed-remove-string-until-final-match-796650/)

Guyverix 03-20-2010 05:19 AM

sed remove string until final match
 
I have been fighting with a sed statement trying to get it to remove everything in a string until the last match and have been failing badly. I need advice on how to get this to work..

sed --> enterprises.9.9.171.1.5.2.1.1.5
returns 5

I want sed to strip everything out until the last period. The final digit can and will change. Some parts before the final period can change as well, since enterprises will sometimes also be represented as more numbers and periods.

If someone could point me in the direction needed, that would be great!
Thanks,

Chris

druuna 03-20-2010 05:23 AM

Hi,

Something like this: sed 's/\([0-9a-zA-Z]*\)\..*\(\.[0-9]\)/\1\2/' input

Sample run:
Code:

$ cat input
enterprises.9.9.171.1.5.2.1.1.5
foo123.9.9.171.1.5.2.1.1.6
456bar.9.9.171.1.5.2.1.1.7

$ sed 's/\([0-9a-zA-Z]*\)\..*\(\.[0-9]\)/\1\2/' input
enterprises.5
foo123.6
456bar.7


Hope this helps.

mario.almeida 03-20-2010 05:29 AM

Hi,
try this

x=enterprises.9.9.171.1.5.2.1.1.5; echo ${x##*.}

or

echo $x | awk -F. '{print $NF}'

Guyverix 03-20-2010 05:32 AM

It helps quite a bit.. I still have to figure out that statement for next time. I have needed to do this more than once, and the results have always been ugly.

Is there a way that you could break down the regex logic there? I am having trouble following it..

Guyverix 03-20-2010 05:34 AM

Quote:

Originally Posted by mario.almeida (Post 3905386)
Hi,
try this

x=enterprises.9.9.171.1.5.2.1.1.5; echo ${x##*.}

or

echo $x | awk -F. '{print $NF}'

Great! That got it perfectly! Thank you!

druuna 03-20-2010 05:38 AM

I guess I misunderstood the question (you only seem to want the last dot and the last number). If that is true:

sed 's/.*\(\.[0-9]\)/\1/' input

This will look for everything ( the first .* ) and a dot followed by any number ( the .[0-9] part). The \( and \) are backreferences, which can be used in the replace part (the \1 part).

Testrun:
Code:

$ sed 's/.*\(\.[0-9]\)/\1/' input
.5
.6
.7

Hope this helps.

nonamenobody 03-20-2010 06:32 AM

Just to explain druuna's answer for Guyverix. The following searches for anything '.*', followed by a fullstop and a single number '\.[0-9]'. Because the last pattern is in parenthesis it is a sub-expression that can used in the replacement.

Code:

$ sed 's/.*\(\.[0-9]\)/\1/' input
Infact, because you want to return a full stop and the last number unchanged you can just use:
Code:

's/.*\././'
Using this the last number won't be matched or replaced and everything upto it will be replaced by a full stop - the number is not being replaced so doesn't need to be included in the search and replace, however the full stop is needed to in the search and replace, because this is our trigger to stop searching.

However, Guyverix didn't want the full stop so all that is needed is:
Code:

's/.*\.//'
BTW, I particularly like Mario's reply - Bash's shell parameter expansion is a very powerful and under-utilised feature.


All times are GMT -5. The time now is 04:57 AM.