This question already has answers here:
Escape a string for a sed replace pattern
(17 answers)
sed search and replace strings containing / [duplicate]
(2 answers)
Closed 3 years ago.
With Bash and SED I'm trying to replace two strings in a js file with URL's.
The two urls that should be inserted is input params when I run the .sh script.
./deploy.sh https://hostname.com/a/index.html https://hostname2.com/test
However to make this usable in my sed command I have to escape all forward slashes with: \\ ?
./deploy.sh https:\\/\\/hostname.com\\/a\\/index.html https:\\/\\/hostname2.com\\/test
If they are escaped this SED command works on Mac OSX Sierra
APP_URL=$1
API_URL=$2
sed "s/tempAppUrl/$APP_URL/g;s/tempApiUrl/$API_URL/g" index.src.js > index.js
Now I don't want to insert escaped urls as params, I want the script it self to escape the forward slashes.
This is what I've tried:
APP_URL=$1
API_URL=$2
ESC_APP_URL=(${APP_URL//\//'\\/'})
ESC_API_URL=(${API_URL//\//'\\/'})
echo 'Escaped URLS'
echo $ESC_APP_URL
#Echos result: https:\\/\\/hostname.com\\/a\\/index.html
echo $ESC_API_URL
#Echos result: https:\\/\\/hostname2.com\\/test
echo "Inserting app-URL and api-URL before dist"
sed "s/tempAppUrl/$ESC_APP_URL/g;s/tempApiUrl/$ESC_API_URL/g" index.src.js > index.js
The params looks the same but in this case the SED throws a error
sed: 1: "s/tempAppUrl/https:\\/\ ...": bad flag in substitute command: '\'
Could anyone tell me the difference here? The Strings looks the same but gives different results.
I suggest to replace
sed "s/regex/replace/" file
with
sed "s|regex|replace|" file
if your sed supports it. Then it is no longer necessary to escape the slashes.
The character directly after the s determines which character is the separator, which must appear three times in the s command.
Related
This question already has answers here:
Escape a string for a sed replace pattern
(17 answers)
Closed 1 year ago.
I have a script that passes a variable into a sed command like this:
sed "s-\t-&${SUBDIRECTORY}/-"
But if the variable contains - (dash), then the sed command throws an error.
So this script:
VARIABLE="test-variable"
sed "s-\t-&${VARIABLE}/-"
Results in this error:
sed: 1: "s-\t-&test-variable/-": bad flag in substitute command: 'v'
I have not been able to find any answers to this issue; it works fine without the -.
How can I fix this?
Use a shell parameter expansion that escapes each instance of -:
sed "s-\t-&${VARIABLE//-/\\-}/-"
In the Bash manual, under Shell Parameter Expansion:
${parameter/pattern/string}
The pattern is expanded to produce a pattern just as in filename expansion. Parameter is expanded and the longest match of pattern against its value is replaced with string. [...] If pattern begins with /, all matches of pattern are replaced with string. Normally only the first match is replaced. [...]
Proper escaping is a fairly difficult problem in the shell, but you could do something like:
$ variable="test-variable"
$ printf '\t\n' | v="$variable" perl -pe 's-\t-$ENV{v}-'
test-variable
This question already has answers here:
How to escape single quote in sed?
(9 answers)
Closed 2 years ago.
I want to replace a set of characters with ' using sed.
This post suggest:
With single quotes around the argument (sed 's/…/…/'), use '\'' to put a single quote in the replacement text.
So, I tried following:
echo 'abcd' | sed 's/[abcd]/\'/g'
But it simply ends up expecting more input:
anir#DESKTOP-4856511:~$ echo 'abcd' | sed 's/[abcd]/\'/g'
>
>
>
> ^C
When I copy pasted echo 'abcd' | sed 's/[abcd]/\'/g' in .sh file and ran, it gave me following error:
anir#DESKTOP-4856511:~/Mahesha999/delete$ ./trysed.sh
./trysed.sh: line 1: unexpected EOF while looking for matching `''
./trysed.sh: line 2: syntax error: unexpected end of file
What the right way to do this? Is it impossible to escape single quote inside single quoted string (and I have to use double quotes only as explained here)?
As the post says:
With single quotes around the argument (sed 's/…/…/'), use '\'' to put a single quote in the replacement text.
So, using your example, you would do:
echo 'abcd' | sed 's/[abcd]/'\''/g'
If you want to replace with just one single quote:
echo 'abcd' | sed 's/[abcd][abcd]*/'\''/g'
The shell does not allow single quotes inside a single quoted string. What the code above does is create three strings (which are not separated by anything):
single-quoted string: 's/[abcd]/'
unquoted string containing just an escaped single-quote: \'
single-quoted string: '/g'
The shell then expands them and because they are not separated, they effectively become joined into a single string.
sed sees: s/[abcd]/'/g
This question already has answers here:
How to insert strings containing slashes with sed? [duplicate]
(11 answers)
Closed 3 years ago.
I am trying the below code to replace the string /IRM/I with E/IRM/I but am getting the file processed with no error and no transformation. I assume I'm using the cancel character incorrectly to allow the forward slash. Any help is much appreciated.
sed -i '/\/IRM\/IE\/IRM\/I/g'
A sed command needs to specify an operation (like s to replace), and that operation requires a sigil. You don't need to use a slash as that sigil.
printf '%s\n' 'This is a test: </IRM/I>' | \
sed -e 's#/IRM/I#E/IRM/I#g'
...correctly emits as output:
This is a test: <E/IRM/I>
Note that we added a s at the beginning of your sed expression, and followed it up with a # -- a sigil that isn't contained anywhere in the source or replacement strings, so you don't need to escape it as you would /.
This question already has answers here:
Replacing some characters in a string with another character
(6 answers)
Closed 3 years ago.
I need to replace the special character which is not alphanumeric with a backslash in a string.
How do i do it in Bash? My version is 4.1
I can capture the special character the plus symbol using the following regex
([^[:alnum:]])
For example, applied to the string
Alan5+6imson
I can do
$ echo $orig_str |sed 's/([^[:alnum:]])/\\1/g'
Alan5+6imson
I need the output as
Alan5\+6imson
How can I replace it in Bash?
I tried the above regex but not sure how to perform a replacement.
Do i need to use some other tool or something like sed?
Would you please try:
echo "$orig_str" | sed 's/\([^[:alnum:]]\)/\\\1/g'
or:
echo "$orig_str" | sed 's/[^[:alnum:]]/\\&/g'
This question already has answers here:
Is it possible to escape regex metacharacters reliably with sed
(4 answers)
Closed 5 years ago.
I have replaced urls in the past using sed with no problem before. However, this url imparticular is giving me trouble. It has quite a few ampersands and I need to replace them. How would I go about doing that?
sed -i.bak "s#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&blah=Y&blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>#<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>#g" path/to/xml/file
My problem is that it's not fully replacing the url. How do I escape the ampersands so I can successfully replace www.url1toreplace.com with www.urltoreplace.com and everything that follows?
In the replacement text, you need to escape &.
For example, without the escape, the whole of the original match is substituted in for each &:
$ echo '&' | sed 's#&#a & b & c#'
a & b & c
With the escape, \&, & is treated as an ordinary character:
$ echo '&' | sed 's#&#a \& b \& c#'
a & b & c
Your example
Let's take this test file:
$ cat file
<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&blah=Y&blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>
And run the original command:
$ sed "s#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&blah=Y&blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>#<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132\&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>#g" file
<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>
The above command fails. If we escape the &, however, we get:
$ sed 's#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&blah=Y&blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>#<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132\&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>#g' file
<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>
This succeeds: the & in the replacement string successfully appears in the output.
Sample data file:
$ cat xfile
<string>https://www.old.home.com?x=123&y=abc&z=ABC_mmc%3D</string>
Desired output:
<string>https://www.new.home.biz?A=XYZ&B=123&C=987_jjj%2XD</string>
As John1024's already pointed out, if a sed replacement string contains &'s, the &'s have to be escaped (\&) (because & has a special meaning to sed).
Hmmmm, but that could be a major pain in the keister if ya gotta go through and (manually?) change all sed replacement patterns from & to \&. But this replacement can be automated with a few minor assumptions ...
Assumptions:
search and replace patterns can be stored in variables before and after, respectively (actually, only the after variable is needed for this idea to work, but for this example I'll use before and after variables)
before and after contain normal strings w/out any special escapes
your version of bash supports character replacement via the ${var// /} construct
Apply escapes to the after variable on the fly:
$ before='old.home.com?x=123&y=abc&z=ABC_mmc%3D'
$ after='new.home.biz?A=XYZ&B=123&C=987_jjj%2XD'
$ sed "s#${before}#${after//\&/\\\&}#g" xfile
<string>https://www.new.home.biz?A=XYZ&B=123&C=987_jjj%2XD</string>
${after//\&/\\\&} : in the after variable, replace all occurrences of & with \&
This eliminates the need to go through and manually escape all occurrences of & in the replacement string.