0

I asked a similar question a while back but I'm hitting a brick wall getting this one to work.

I'm scripting the modification of a config file laid out like this:

[Thing1]
    [[subthingA]]
        this = 0
        that = string
        and = localhost
        the = 80
        other = 0
        thing_ading = /path/to/a/dir

[Thing2]
    [[subthingB]]
        this = 0
        thing_ading = /path/to/dir
        here = 0

Where there are N number of [Things], often with the same key and/or value of a key/value pair, and the key/value pairs under the [[subthings]] are indented by exactly 8 spaces. I'm specifically trying to craft a one-liner using awk/sed/grep/tr/cut/perl that can change the value of thing_ading under SubthingB to a different directory path.

I'm able to edit all thing_adings and I've been able to target certain pairs, but the spaces are really giving me an issue.

2
  • add expected output as well as code you tried
    – Sundeep
    Jul 5, 2017 at 6:25
  • You should probably search for "ini-file parser". Add "bash" to the query if you want something for bash.
    – Kusalananda
    Jul 5, 2017 at 6:30

2 Answers 2

0

You can tackle such problems using sed's range operator ,:

sed -e '
   /^\[Thing2]$/,/^$/!b
   /^[[:blank:]]\{4\}\[\[subthingB]]/,/^$/s|^\([[:blank:]]\{8\}thing_ading\) = .*|\1 = /YOUR/NEW/PATH/TO/DIR|
' yourinifile
  • First you select the proper range by skipping improper ranges.
  • Then when in proper range, you perform the substitution on the thing_ding variable required.
1
  • This worked perfectly, thanks! (And thanks for the brief explanation as well).
    – user212683
    Jul 5, 2017 at 15:29
0

Here is an sed one-liner:

sed '/[[subthingB]]/,/^ *\[/{/thing_ading =/s_=.*_= /your/path/_}' config_file

To work only on the subthingB block, we address everything from [[subthingB]] to the next line starting with [ after the indent.

Now, for this block, we address the thing_ading line and do the replacement, using _ instead of / as delimited for the s command to avoid backslashing the replacement to unreadability.

If the subthingB block is guaranteed to have an thing_ading entry, you can simplify to

sed '/[[subthingB]]/,/thing_ading =/{//s_=.*_= /your/path/_}'

reusing the last pattern for inner addressing.

You must log in to answer this question.