Bt_code
Bt_code

Reputation: 41

remove substring from a string with special characters using sed

Scenario 1:

string1=hello_how_are_you
string2=hello_ho
echo $string1 | sed -e "s/${string2}//g"
output : w_are_you

Scenario 2:

rule='\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null'
placement_rule='{\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}'

echo $placement_rule |  sed -e "s/${rule}//g"

output : {\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}

As you can see in scenario2 no change in output, what can be done to replace /remove strings like these using sed.

Expected output should have been:

{},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}

Thanks

Upvotes: 1

Views: 82

Answers (3)

Ed Morton
Ed Morton

Reputation: 204628

Just use a tool like awk that understands literal strings (unlike sed which only understands regexps and backreference-enabled replacement text):

$ rule='\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null'

$ placement_rule='{\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}'

.

$ echo "$placement_rule" | rule="$rule" awk 'BEGIN{rule=ENVIRON["rule"]; n=length(rule)} s=index($0,rule){$0=substr($0,1,s-1) substr($0,s+n)} 1'
{},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}

or:

$ echo "$placement_rule" | awk 'BEGIN{rule=ARGV[1]; ARGV[1]=""; n=length(rule)} s=index($0,rule){$0=substr($0,1,s-1) substr($0,s+n)} 1' "$rule"
{},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}

See http://cfajohnson.com/shell/cus-faq-2.html#Q24 for info on why I'm using ENVIRON orARGV[1]to pass the shell variables value in rather than-v`, i.e. backslashes are only literal the way I'm doing it.

Upvotes: 1

agc
agc

Reputation: 8446

If the job is just to empty the first set of curly braces, it would be simpler not to use a complex ${rule} variable, and just clear out those braces:

sed 's/{[^}]*}/{}/' <<< $placement_rule

Upvotes: 0

tshiono
tshiono

Reputation: 22087

Please try the following:

rule='\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null'
rule="$(echo "$rule" | sed -e 's/\\/\\\\\\/g')"    # This line escapes the backslashes
placement_rule='{\"create\":false,\"name\":\"specified\",\"queue\":null,\"rules\":null},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}'

echo $placement_rule |  sed -e "s/${rule}//g"

Output:

{},{\"create\":false,\"name\":\"primaryGroup\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"secondaryGroupExistingQueue\",\"queue\":null,\"rules\":null},{\"create\":null,\"name\":\"default\",\"queue\":null,\"rules\":null}
  • The variable $rule needs to have escape sequences as \\\" which is then interpreted as \" in the sed replacement.
  • The added conversion s/\\/\\\\\\/g replaces single backslash with three sequential backslashes.

Upvotes: 0

Related Questions