0

I am trying to do a sed replacement which I am currently doing with two commands. I can't figure out how to combine the two commands together so that it replaces the words correctly in one go.

My role here is to append sc_admin to every place which has the words admin in there.

Below are all the combinations of words that I can think of:

access = read : [ admin ], write : [ admin, power ]
access = read : [ security_pan_power ], write : [ security_pan_power ]
access = read : [ * ], write : [ admin, wis_master, wis_read_only, wis_web ]
access = read : [ admin ]
access = read : [ admin, somerole ], write : [ admin, power ]

So currently I am using 2 sed commands to do replacements

sed -e '/\bsc_admin\b/b' -e '/admin/ s/ *]/, sc_admin ]/' infile

replaces the word admin in the read portion correctly but does not replace the word admin in the write portion.

for example

access = read : [ admin, sc_admin ], write : [ admin, power ]
access = read : [ security_pan_power ], write : [ security_pan_power ]
access = read : [ *, sc_admin ], write : [ admin, wis_master, wis_read_only, wis_web ]
access = read : [ admin, sc_admin ]
access = read : [ admin, somerole, sc_admin ], write : [ admin, power ]
access = read : [ defadmin, somerole, sc_admin ], write : [ admin, power ]

while

 sed -e '/\bsc_admin\b/b' -e '/admin/ s/ *] *$/, sc_admin ]/'

command appends the word admin in the write portion correctly while it does not do anything to the read portion.

access = read : [ admin ], write : [ admin, power, sc_admin ]
access = read : [ security_pan_power ], write : [ security_pan_power ]
access = read : [ * ], write : [ admin, wis_master, wis_read_only, wis_web, sc_admin ]
access = read : [ admin, sc_admin ]
access = read : [ admin, somerole ], write : [ admin, power, sc_admin ]
access = read : [ defadmin, somerole ], write : [ admin, power ]

So currently I am running one command and then I am running the second command to fix the files. Is there a fool-proof way to combine the commands so that I get the proper output?

This is the actual output that I desire:

access = read : [ admin, sc_admin ], write : [ admin, power, sc_admin ]
access = read : [ security_pan_power ], write : [ security_pan_power ]
access = read : [ * ], write : [ admin, wis_master, wis_read_only, wis_web, sc_admin ]
access = read : [ admin, sc_admin ]
access = read : [ admin, somerole, sc_admin ], write : [ admin, power, sc_admin ]
3
  • Should we assume you are using GNU sed? If you are using Linux the answer is yes.
    – terdon
    May 11 at 13:52
  • i am running this on my Mac. is that not GNU sed? i am only a few months into learning bash scripting. so im still a noob. May 11 at 13:55
  • 1
    Nothing wrong with being a noob! We were all noobs once. And no, that probably means you don't have GNU sed, I was just surprised to see the \b working, I thought that was GNU-only, but I may well be wrong. Is the order of the entries inside each [ ] important? Isn't it enough to just do sed 's/\badmin\b/&, sc_admin/g' infile?
    – terdon
    May 11 at 14:05

1 Answer 1

3

You can do the following with sed:

$ sed 's/\(\[ admin[^]]*\) /\1, sc_admin /g' file 
access = read : [ admin, sc_admin ], write : [ admin, power, sc_admin ]
access = read : [ security_pan_power ], write : [ security_pan_power ]
access = read : [ * ], write : [ admin, wis_master, wis_read_only, wis_web, sc_admin ]
access = read : [ admin, sc_admin ]
access = read : [ admin, somerole, sc_admin ], write : [ admin, power, sc_admin ]


  • \(\[ admin[^]]*\) capture the string '[ admin<every character that is not a ] and a final space>. For this we enclose the capture between \(...\), and use [^]]* to select characters that are not(^) ']'.

  • \1, sc_admin substitute with the captured group (\1) and append ', sc_admin'.

2
  • spot on. it will take me a day to completely understand the command but this works exactly the way i want. I am still new to bash but i will figure out the whole command. Thanks. May 11 at 14:33
  • 1
    @ranjitabraham I added an explanation, I hope it helps, if in doubt just tell me. May 11 at 14:41

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.