Last active
July 10, 2024 00:19
-
-
Save msamendinger/c2da6f5fafc43e72ef576a0cc7ad0165 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# what happens when we want to replace a string with a variable with a forward slash in its value? | |
$ var1="test/string" | |
$ echo "this is a test" | sed "s/test/$var1/" | |
sed: 1: "s/test/test/string/g": bad flag in substitute command: 's' | |
# set has delimiter confusion let's use another delimiter | |
$ echo "this is a test" | sed "s#test#$var1#" | |
this is a test/string | |
# works but what if we want to use #s | |
$ var2="test/string # comment" | |
$ echo "this is a test" | sed "s#test#$var2#" | |
sed: 1: "s#test#test/string # co ...": bad flag in substitute command: 'c' | |
# again delimiter confusion | |
# We have to escape the forward slash with \ should be easy with sed... wait :thinking: | |
# as we're already fighting with sed let's use bash parameter expansion | |
$ echo "this is a test" | sed "s/test/${var2/\//\\/}/" # replace / with \/ | |
this is a test/string # comment | |
# what about two forward slashes? | |
$ var3="test//string # comment" | |
$ echo "this is a test" | sed "s/test/${var3/\//\\/}/" | |
sed: 1: "s/test/test\//string # ...": bad flag in substitute command: 's' | |
# what happened? | |
$ echo ${var3/\//\\/} | |
test\//string # comment | |
# only one forward slash got replaced | |
# we begin our parameter expansion with a forward slash to replace all matches | |
# makes it even easier to read, right? | |
$ echo "this is a test" | sed "s/test/${var3//\//\\/}/" | |
this is a test//string # comment | |
# great, now that we have that working lets use | |
$ var4="test//string # comment about using \ backslash" | |
$ echo "this is a test" | sed "s/test/${var4//\//\\/}/" | |
this is a test//string # comment about using backslash | |
# we're missing the backslash. Ok back to work, we have to escape the backslash | |
# bash parameter expansion does not allow multiple substitutions so back to sed | |
# in a first step let's escape the forward slashes only, we use /g to replace | |
# all matches | |
# we escape every / as \/ and every \ as \\ | |
$ var5=$(sed "s/\//\\\//g" <<< $var4) | |
sed: 1: "s/\//\\//g": bad flag in substitute command: '/' | |
# what? if something is not working just add more backslashes... | |
# escape all escape characters. | |
$ var5=$(sed "s/\//\\\\\//g" <<< $var4) | |
$ echo $var5 | |
test\/\/string # comment about using \ backslash | |
$ echo "this is a test" | sed "s/test/$var5/" | |
this is a test//string # comment about using backslash | |
# this is fine as the backslash did get no love yet. | |
# but now that we know we have to use 4 backslashes to match 1 its easy | |
$ var5=$(sed "s/\\\\/\\\\\\\\/g; s/\//\\\\\//g;" <<< $var4) | |
$ echo "this is a test" | sed "s/test/$var5/" | |
this is a test//string # comment about using \ backslash |
Oh I missed your comment. You're right arbitrary single byte characters can be used. On line 6 I used a hash as delimiter. The text I wanted to replace was not known before and unstructured so I wasn't sure what character I can safely use.
With single quotes the situation would have also improved
var5=$(sed 's/\\/\\\\/g; s/\//\\\//g;' <<< $var4)
At the end this shouldn't be taken too serious ;)
can't thank you enough man it saved my live
btw
match="a="somethinng""
replace="b="somme/some""
how to escape " and / here with sed ??
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi,
I came accross here after I had to replace with a string containing slashes... Just to let you know, you can actually use any single byte character as a separator in sed.
sed -i "s|$match|$replace|" file