6

I'm having a hard time figuring out how to use sed to cut text before a certain delimiter.

I'm receiving output from echo that returns something similar to:

valueA=TEXT

I would like to have sed cut the text before = and leaving only TEXT.

Any tips on how it can be done?

  • 3
    It's not entirely clear where the output comes from but the right tool for this job is either cut or parameter expansion (not to say that sed can't do it...) – don_crissti Dec 10 '16 at 17:20
  • My bad @don_crissti! Output is coming from echo. I'll try and edit OP. – t988GF Dec 10 '16 at 17:53
  • 2
    AWK awk -F= '{print $2} SED: sed -e s/^[^=]*=// – Archemar Dec 10 '16 at 17:55
  • Thank you @Archemar! sed example worked exactly as intended! – t988GF Dec 10 '16 at 17:58
  • 2
    i concur with @don_crissti - in a case as simple as this, " ...| cut -d = -f 2- " is much simpler - to type at least – Michael Felt Dec 10 '16 at 18:07
8

You can also use cut :

cut -d= -f2- <<< "$yourvar"

or

some_command | cut -d= -f2-
  • -d= sets the delimiter to =
  • -f2- takes the second field and all the following ones
5

From @Archemar's comment, which should probably have been an answer:

sed -e s/^[^=]*=//

From @Baard Kopperud's comment, the sed command can be explained as:

Substitute lines (s/) beginning (^) with any number of characters (*) except "=" ([^=]) followed by an equation-sign (=) with nothing (//). This will remove anything from the beginning of the line, to and including the equal-sing - leaving just what comes after the "=". You need the "[^=]*" in case there are multiple equal-signs... you just want to delete up to the first one. If you just used ".*", then you'd cut up to and including the last equal-sign, as regular expressions "wish" to be as long as possible, and starting as far to the left as possible.

  • 1
    Well, at least do explain sed command. – Archemar Dec 10 '16 at 19:02
  • Substitute lines (s/) beginning (^) with any number of characters (*) except "=" ([^=]) followed by an equation-sign (=) with nothing (//). This will remove anything from the beginning of the line, to and including the equal-sing - leaving just what comes after the "=". You need the "[^=]*" in case there are multiple equal-signs... you just want to delete up to the first one. If you just used ".*", then you'd cut up to and including the last equal-sign, as regular expressions "wish" to be as long as possible, and starting as far to the left as possible. – Baard Kopperud Dec 10 '16 at 19:37
  • @BaardKopperud, just edit the explanation into the answer. Comments are ephemeral. – Wildcard Dec 10 '16 at 22:26
2

I'm receiving output from echo

If you're forming that echo from a variable, you can use the shell's built-in string manipulation capabilities:

# Instead of value=$(echo "$var" | cut -d= -f2-)
value=${var#*=}

The *= is just a glob-style pattern, where * matches anything. The # indicates that the pattern matches a prefix to be removed from the variable.

This will ultimately be faster and more reliable than piping from echo, as it avoids the trouble xpg_echo can land you in (as well as other parsing quirks of echo), and it avoids a fork.

You can also get the key using this method:

key=${var%%=*}

Note that %% is used rather than % to match greedily. With that, it won't be tripped up by any potential =-signs in the value.

The syntax is documented in man bash, under Parameter Expansion:

   ${parameter#word}
   ${parameter##word}
          Remove matching prefix pattern.  The word is expanded to produce
          a pattern just as in pathname expansion.  If the pattern matches
          the  beginning of the value of parameter, then the result of the
          expansion is the expanded value of parameter with  the  shortest
          matching  pattern  (the ``#'' case) or the longest matching pat‐
          tern (the ``##'' case) deleted.  If parameter is  @  or  *,  the
          pattern  removal operation is applied to each positional parame‐
          ter in turn, and the expansion is the resultant list.  If param‐
          eter  is  an array variable subscripted with @ or *, the pattern
          removal operation is applied to each  member  of  the  array  in
          turn, and the expansion is the resultant list.

   ${parameter%word}
   ${parameter%%word}
          Remove matching suffix pattern.  The word is expanded to produce
          a pattern just as in pathname expansion.  If the pattern matches
          a  trailing portion of the expanded value of parameter, then the
          result of the expansion is the expanded value of parameter  with
          the  shortest  matching  pattern (the ``%'' case) or the longest
          matching pattern (the ``%%'' case) deleted.  If parameter  is  @
          or  *,  the  pattern  removal operation is applied to each posi‐
          tional parameter in turn, and the  expansion  is  the  resultant
          list.   If  parameter is an array variable subscripted with @ or
          *, the pattern removal operation is applied to  each  member  of
          the array in turn, and the expansion is the resultant list.

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.