3

Hello I am trying to do a replace on a file where a string is followed by any random string using sed. My original file looks like below.

access = read : [ * ], write : [ admin, sc_admin ]
access = read : [ * ], write : [ admin, myuser ]
access = read : [ * ], write : [ admin ]
access = read : [ * ], write : [ admin, randomuser ]
access = read : [ * ], write : [ admin, randomuser, somedude ]
access = read : [ * ], write : [ admin, justarandomuser, somedude, anotherdude ]
access = read : [ * ], write : [ admin, another_random_user ]

I need to add a string called sc_admin after my random user which follows admin so that it looks like this

access = read : [ * ], write : [ admin, sc_admin ]
access = read : [ * ], write : [ admin, myuser, sc_admin ]
access = read : [ * ], write : [ admin ]
access = read : [ * ], write : [ admin, randomuser, sc_admin ]
access = read : [ * ], write : [ admin, randomuser, somedude, sc_admin ]
access = read : [ * ], write : [ admin, justarandomuser, somedude, anotherdude, sc_admin ]
access = read : [ * ], write : [ admin, another_random_user, sc_admin ]

I am trying to run the following sed command but its not doing anything.

sed -r "s/\[\ admin\,\ \w+\ \]/\[\ admin\,\ \w+\,\ sc\_admin\ \]/g" local.meta 

what am i missing here?

3
  • admin followed by randomuser or random_user
    – Inian
    Commented Mar 31, 2022 at 7:00
  • Do you ever have input lines that do not contain an admin user? If so include one of those in your question so we can see how they should be handled.
    – Ed Morton
    Commented Mar 31, 2022 at 13:27
  • 2
    When posting sample input/output you should try to think of cases that'd be difficult to get right, not just the trivial cases. It's always much easier to match the strings you want than to not match similar strings you don't want. Try the answers provided so far if your input was access = read : [ * ], write : [ admin, mollusc_administered ] for example (they'd fail because it contains the substring sc_admin) . Take a minute to think about cases where a script might fail (e.g. false matches on substrings, regexp instead of string matches) and add those to your example.
    – Ed Morton
    Commented Mar 31, 2022 at 14:15

3 Answers 3

1

Skip lines that already contain sc_admin, then replace only on lines containing admin,:

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

Output:

access = read : [ * ], write : [ admin, sc_admin ]
access = read : [ * ], write : [ admin, myuser, sc_admin ]
access = read : [ * ], write : [ admin ]
access = read : [ * ], write : [ admin, randomuser, sc_admin ]
access = read : [ * ], write : [ admin, randomuser, somedude, sc_admin ]
access = read : [ * ], write : [ admin, justarandomuser, somedude, anotherdude, sc_admin ]
access = read : [ * ], write : [ admin, another_random_user, sc_admin ]
2
  • This is perfect. Thank you Thor. :) Commented Mar 31, 2022 at 7:19
  • Why E? I don't think u use ERE here Commented Mar 31, 2022 at 16:37
1

Using sed

$ sed '/sc_admin\>/!s/\[ admin,.*[a-z]/&, sc_admin/' input_file
access = read : [ * ], write : [ admin, sc_admin ]
access = read : [ * ], write : [ admin, myuser, sc_admin ]
access = read : [ * ], write : [ admin ]
access = read : [ * ], write : [ admin, randomuser, sc_admin ]
access = read : [ * ], write : [ admin, randomuser, somedude, sc_admin ]
access = read : [ * ], write : [ admin, justarandomuser, somedude, anotherdude, sc_admin ]
access = read : [ * ], write : [ admin, another_random_user, sc_admin ]
4
  • That would fail if randomuser was mollusc_administered.
    – Ed Morton
    Commented Mar 31, 2022 at 14:12
  • @EdMorton Good catch. However, that would be a case of adding a slash in the regex match, but yes, in its current format, it would fail.
    – sseLtaH
    Commented Mar 31, 2022 at 14:57
  • 1
    It'd take a bit more than adding a slash in the regexp match, e.g. word boundaries if you want to go GNU-only, or testing for blanks, commas, or square brackets otherwise (I think, haven't thought it through as the OP hasn't provided sample input/output to really test it yet).
    – Ed Morton
    Commented Mar 31, 2022 at 15:33
  • 1
    @EdMorton Indeed. Obviously, I did not think it through either ; )
    – sseLtaH
    Commented Mar 31, 2022 at 15:41
0
awk '!/sc_admin/ && /admin,/{gsub(/\]$/,",scadmin ]",$0)}1' filename

output

access = read : [ * ], write : [ admin, sc_admin ]
access = read : [ * ], write : [ admin, myuser ,scadmin ]
access = read : [ * ], write : [ admin ]
access = read : [ * ], write : [ admin, randomuser ,scadmin ]
access = read : [ * ], write : [ admin, randomuser, somedude ,scadmin ]
access = read : [ * ], write : [ admin, justarandomuser, somedude, anotherdude ,scadmin ]
access = read : [ * ], write : [ admin, another_random_user ,scadmin ]

You must log in to answer this question.

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