Seun
Seun

Reputation: 83

Multiple SED -E commands

So I have multiple sed commands I will like to put together as one. Any pointer will be appreciated, I believe this is a sort of advanced SED and I have tried to no success:

sed -E '/limits:/!b;n;s/^([[:blank:]]*cpu: ).*/\\1900m/' mychart.yaml
sed -E '/limits:/!b;n;n;s/^([[:blank:]]*memory: ).*/\\1900Mi/' mychart.yaml
sed -E '/requests:/!b;n;s/^([[:blank:]]*cpu: ).*/\\1700m/' mychart.yaml
sed -E '/requests:/!b;n;n;s/^([[:blank:]]*memory: ).*/\\1500Mi/' mychart.yaml

Below is the mychart.yaml context I am using the above commands to replace the values:

      resources:
        limits:
          cpu: 500m
          memory: 512Mi
        requests:
          cpu: 250m
          memory: 256Mi

Thank you all!

Upvotes: 1

Views: 431

Answers (2)

anubhava
anubhava

Reputation: 785561

To combine all the sed commands I suggest a cleaner approach to put them all in a sed command text file like this:

cat parse.sed

/limits:/ {
   n
   s/^([[:blank:]]*cpu: ).*/\1900m/
   n
   s/^([[:blank:]]*memory: ).*/\1900Mi/
}
/requests:/ {
   n
   s/^([[:blank:]]*cpu: ).*/\1700m/
   n
   s/^([[:blank:]]*memory: ).*/\1500Mi/
}

Then use it as:

sed -E -f parse.sed mychart.yaml

     resources:
        limits:
          cpu: 900m
          memory: 900Mi
        requests:
          cpu: 700m
          memory: 500Mi

Upvotes: 1

tripleee
tripleee

Reputation: 189648

Your scripts cannot be trivially combined because they each contain instructions to skip the rest of the script (the b commands). You will need some refactoring to make it work.

In brief, this replaces each !b with a set of braces which say what to do when the condition matches, instead of simply saying "do nothing and skip to the end of the script if it doesn't match". Because several of these conditions overlap, they had to be further combined to do the second n after the first instead of repeating the same condition again.

sed -E -e '/limits:/{;n;s/^([[:blank:]]*cpu: ).*/\1900m/'\
       -e 'n;s/^([[:blank:]]*memory: ).*/\1900Mi/;}' \
       -e '/requests:/{;n;s/^([[:blank:]]*cpu: ).*/\1700m/' \
       -e  'n;s/^([[:blank:]]*memory: ).*/\1500Mi/;}' mychart.yaml

The doubled backslashes also looked wrong, so I switched those to single ones.

For the record, the -E option (or other options like -i or -r) don't change the fundamental syntax; you use multiple -e option to specify multiple pieces of script.

Different sed dialects have different rules for when you need newlines or semicolons e.g. around braces, so this might not work out of the box on all platforms. I tested on MacOS which is typically rather conservative and crude, so if it works there, I guess it should work most other places, too.

But as others have already pointed out, using a proper YAML parser is a much, much, much better solution.

Upvotes: 1

Related Questions