How to add 12spaces to the next line after the string match in shell?

All we need is an easy explanation of the problem, so here it is.

I have a file called config.toml. I am doing the string match with runc.options as highlighted in the image. I need to insert a string "Systemdgroup = true" after 12 spaces. I tried the below command, which works, but used manual white 12 spaces. How it can be achieved in another way?

sed -e "/runc.options/a\            SystemdCgroup = true" /etc/containerd/config.toml

How to add 12spaces to the next line after the string match in shell?

Instead of typing literally 12 spaces, anything like /s+12 work?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You cannot really do this directly with REGEX patterns, but you may (ab)use printf‘s option for left-patting with spaces and an empty string:

sed "/pattern/a$(printf '\%12s')SystemCgroup = .../" file 

Note that the percent sign needs to be escaped.

Method 2

Using the TOML parser tomlq (from https://kislyuk.github.io/yq/):

tomlq -t '.plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options.SystemdCgroup |= true' config.toml

Use tomlq with its --in-place (or -i) option to make an in-place edit.

The expression used with tomlq above is a jq expression (tomlq is a jq wrapper) which sets the specific key in the document’s structure to the value true.

Note that the spacing in the document does not matter for the validity of the document structure.


In general, with sed, if you want to insert a line of text at the same indentation depth as a previous line, consider reusing the indentation of that previous line.

/^\([[:blank:]]*\)\[.*runc\.options\].*/ {
    h
    s//\1  SystemdCgroup = true/
    H
    g
}

This sed script matches the specific section label we’re looking for and remembers the number of blanks preceding the [ on that line. It saves a copy of the line in the hold space, replaces the line in the buffer with our new data, using \1 to insert the original indentation. Then appends the buffer to the hold space (which inserts a newline character) and fetches the hold space into the editing buffer to be printed.

Note, however, that sed and similar line-oriented tools are often inadequate for working with structured document formats such as TOML, YAML, JSON, and XML. These formats are not always line-delimited as they may require a particular encoding of data.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply