-1

I have a file in which i have to find a String and replace it. It giving me error when i am using sed because the replace string contains "/".

replace_string=6W4kngjd3c7oOShnG7iWYQpZVzr4S88G20fujmP7cdM1m5Gw550WfMD38DA4g6O4qxUIJJwt2OtLTRmh7vWz+AWQVmIMajk3OylEfR/X+afrD6YOeGLYHU6Ef4DYv/3x

sed -i -e 's|string|'$replace_string'|g' $FILEPATH

This is the error which its giving - sed: -e expression #1, char 38: unterminated `s' command

Is there any other method other than sed or any other way i can use sed?

Ed Morton
  • 188,023
  • 17
  • 78
  • 185

2 Answers2

3

sed doesn't understand literal strings (see Is it possible to escape regex metacharacters reliably with sed), only regexps and backreference-enabled replacements that can't contain whatever delimiters you use. If you want to replace a string then use a tool that understands strings such as awk, e.g. this will work for any characters in your strings (code would need tweaked to handle newlines within old or multiple substitutions on a single line):

old='string1' new='string2' awk '
BEGIN {
    old = ENVIRON["old"]
    new = ENVIRON["new"]
    lgth = length(old)
}
s = index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+lgth) }
{ print }
' file
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • This is working when there is no backslash in replace_string – Sudarshan Rampuria Jun 13 '20 at 12:03
  • 1
    It'll work even if there is a backslash in replace_string, it treats all characters literally. – Ed Morton Jun 13 '20 at 12:04
  • This prints the full file with the changes. Can't it make changes to the file? – Sudarshan Rampuria Jun 13 '20 at 12:18
  • Sorry i am a bit new to bash scripting – Sudarshan Rampuria Jun 13 '20 at 12:18
  • 1
    @SudarshanRampuria Above solution works for the input provided. Please edit the question and add more information like sample input and expected output. `Can't it make changes to the file?` Add this to the original question. Check [How do I ask a good question? ](https://stackoverflow.com/help/how-to-ask) – Digvijay S Jun 13 '20 at 12:20
  • 2
    Standard UNIX tools (other than file editors like `ed`, `vi`, and `emacs` of course) do not make changes to the file you run them on, they just produce output and then it's up to you to redirect that as you like. GNU awk has `-i inplace` just like GNU sed and OSX/BSD sed have `-i`. If you don't have one of those then with any UNIX tool `cmd` you can simply run `cmd file > tmp && mv tmp file` - that's what the tools I just mentioned do internally anyway. So in this case if you don't have GNU awk for `-i inplace` then you'd do `old='string1' new='string2' awk 'script' file > tmp && mv tmp file`. – Ed Morton Jun 13 '20 at 12:20
0

ripgrep is another tool that allows to search and replace literally. The substitution capability is limited compared to sed (for ex: it always replaces all occurences like g flag)

$ cat ip.txt
2.3/[4]*6+[4]*2
foo
5.3-[4]*9

$ rg -N --passthru -F '[4]*' -r '\&/' ip.txt
2.3/\&/6+\&/2
foo
5.3-\&/9


For inplace editing:

rg --passthru -F 'old' -r 'new' ip.txt > tmp && mv tmp ip.txt

With shell variables:

rg --passthru -F "$old" -r "$new" ip.txt > tmp && mv tmp ip.txt

-N flag not required when redirecting output of rg

Sundeep
  • 23,246
  • 2
  • 28
  • 103