2

I have a requirement where we need to replace a word in a file which can be different everytime I execute the script, the content of the file is

class DynamicContentToReplace > Something

Here I need to use sed command to replace [DynamicContentToReplace] with RequiredContent. The [DynamicContentToReplace] could include everything except white spaces.

Assumptions we can take is that the file will only contain one such line containing class word

Desired Output

class RequiredContent > Something

I have tried the following command sed -e "s/\(class \)\([^\s]+\)/\1RequiredContent/" but it still does not replace the content. What am i missing here. I have gone through this post as well. But couldn't get the solution.

4
  • What is the desired output ? What's the > Something part ? Something on the same line?
    – golder3
    Feb 4, 2022 at 12:53
  • @golder3 updated the desired output, and yes > Something part is on the same line. Feb 4, 2022 at 13:00
  • 1
    What is unique about that line? Can class appear on any other lines? Can foo bar > appear on other lines? How can we identify the bit that needs to change?
    – terdon
    Feb 4, 2022 at 13:02
  • @terdon updated the question. yes class word will only appear once in the entire file. We can identify the word to replace using that Feb 4, 2022 at 13:14

3 Answers 3

4
  • For Basic Regex, you need to escape the + quantifier.
  • \+ is a GNU extension, you may need to use * or \{1,\} instead.
  • Use [^[:space:]] or simply [^ ] instead of [^\s]. With GNU sed you could also use \S for anything but whitespace.
  • No need to capture the second group, as you don't use \2 anywhere.
  • If you have only one sed command, there is no need for -e
  • You might want to add ^ in front of class to not replace unwanted things like instance=my_class_something()

Use:

sed 's/^\(class \)[^[:space:]]*/\1RequiredContent/'

or use Extended Regex (sed -E):

sed -E 's/^(class )\S+/\1RequiredContent/'
4
  • for me the first solution does not work, it does not replace anything. The second one using extended Regex does. Thanks @pLumo Feb 4, 2022 at 13:05
  • 1
    Note that \+, \S, \s are GNU extensions (\s/\S obviously inspired from perl) Feb 4, 2022 at 13:17
  • also for extended regeX?
    – pLumo
    Feb 4, 2022 at 13:19
  • 1
    -E is from BSD sed. GNU sed had -r for that. GNU sed later added a hidden -E for compatibility with BSD, and later unhid it as POSIX plans to add it to standard sed (already there in drafts of the next version). But in any case, there's no \s / \S in standard BRE nor EREs. There is + in standard ERE, the standard BRE equivalent being \{1,\}. Feb 4, 2022 at 13:22
3

Since you're using perl regexp operators, why not just use perl?

perl -pe 's/\bclass\s+\K\S+/RequiredContent/g' < your-file
  • \b is a word boundary operator, it will match as long as there's no word character before class.
  • \s matches any whitespace character (limited to ASCII ones as we did not tell perl to decode the input in the user's locale or UTF-8¹, so the input is interpreted as if encoded in ISO8859-1 (thankfully the 0xa0 byte, ISO8859-1's non-breaking space encoding not being considered whitespace as long as you don't add the u flag to that substitution).
  • \K resets the start of the matched string, so only what's matched after that will be replaced, so you don't need to capture what's before to add it back in the replacement.
  • \S is any non-whitespace. In perl, that's equivalent to [^\s] while in sed, [^\s] would match any character other than \ and s.

¹ assuming the PERL_UNICODE environment variable is not set

0

I propose this, assuming 'class' is always there ans is at the start of the line:

$ sed 's/^class [^ ]*/class RequiredContent/'
class RequiredContent > Something

  • [^ ]* substitue everything that's not a blank after 'class ' with 'class ' plus the required new string.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .