I need to delete everything between the second = in a string and the first / in a string, but keep the = in place. I've tried many, many things, the most recent of which is

sed -i 's/=[^/]*//
  • 1
    Can you edit your post and add a sample input and what your expected output is? – MikeA Sep 28 '16 at 21:46

Started writing about look-ahead and look-behind assertions only to learn that sed doesn't support them! This should do the trick:

sed -i 's!\(=[^=]*=\)[^/]*/!\1!'

  • Since we use / character in the regexp, we change delimiter of s command to !
  • \(=[^=]*=\) is a capture group that matches one = character followed by zero or more other characters followed by another = character. This part is needed to make sure there are two = characters before the to-be-deleted substring as you said you need to
  • [^/]*/ matches whatever is between delimiters and the second delimiter
  • \1 replaces the whole matched string with whatever matched the capture group \(=[^=]*=\)
  • This was perfect! Thank you for the detailed explanation as well. – Jeff Carson Sep 29 '16 at 12:22
  • Is it possible to do this same thing but skip the first = in the line? So same command, only beginning with the second occurance of =. – Jeff Carson Oct 28 '16 at 18:22
  • Not quite sure what you mean, Jeff. Can you give some sample in/output? – bazzilic Oct 29 '16 at 11:27

Based only on the text description, with no sample input/output, I came up with this:

$ echo "foo=bar=baz/quux" | sed 's/\(.*=.*\)=.*\/\(.*\)/\1=\2/'

How close does that come to what you want?

  • My apologies for not having a desired output. I will be sure to include that in future post. That said the output John shows above is exactly what I am looking for. It seems to cut everything after the 2nd = to the / but it leaves the = in place which is exactly my use case. I will try it would live data when I get back to my computer later this evening. Thank you very much for your input. – Jeff Carson Sep 28 '16 at 22:34

Here's one solution with perl

$ echo 'foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'

$ echo 'abc=foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'

As can be seen from examples above, this restricts to deleting text only from 2nd = to /

  • ^([^=]+=){2}\K from start of line find 2 sequence of non-= text followed by =. The \K means positive lookbehind, not part of replacement string
  • [^=/]+/ means one or more non-=/ characters ending with /
    • If such a text is found, it gets deleted

Same solution with sed

$ echo 'foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'

$ echo 'abc=foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'

It doesn't support lookahead/lookbehind constructs, so capture group used and backreferenced while replacing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.