Sed replacement not working when using variables [duplicate] - linux

This question already has answers here:
Replace a string in shell script using a variable
(12 answers)
Closed 9 years ago.
something strange is happening when trying to replace string with sed. This works :
find /home/loni/config -type f -exec sed -i 's/some_pattern/replacement/g' {} \;
So it works when I manually type the strings. But in the case below replacement doesn't occur :
find /home/loni/config -type f -exec sed -i 's/${PATTERN}/${REPLACEMENT}/g' {} \;
When I echo these two variables PATTERN and REPLACEMENT they have the correct values.
I'm trying to replace all occurences of pattern string with replacement string in all files in my config directory.

Try
find /home/loni/config -type f -exec sed -i "s/${PATTERN}/${REPLACEMENT}/g" {} \;
instead. The ' quotes don't expand variables.

Not sure if I got this right, but if you want to replace the ${PATTERN} with ${REPLACEMENT} literally you have to escape the dollar and maybe the braces, those are reserved characters in regular expressions:
find /home/loni/config -type f -exec sed -i -e 's/\$\{PATTERN\}/\$\{REPLACEMENT\}/g' {} \;

Related

Using sed editor to replace a string containing backslash [duplicate]

This question already has answers here:
How to insert strings containing slashes with sed? [duplicate]
(11 answers)
Closed 5 years ago.
How can i use the sed to replace string containing backslash "\" is all files of specific directory.
I tried this but wont work for me
find /home/tds/nfb -type f -exec sed -i 's//var/www/tds///home/tds//' {} \;
I want to replace "/var/www/tds/" with "/home/tds/"
You can do
find /home/tds/nfb -type f -exec sed -i 's|/var/www/tds/|/home/tds/|' {} \;
where the delimiter / is replaced by |. (sed can use almost any character as a delimiter -- it picks whatever character follows the s). Alternatively, you could escape all your backslashes as follows and still used \:
sed -i 's/\/var\/www\/tds\//\/home\/tds\//'

Replace all \\ with / in files and subdirs [duplicate]

This question already has answers here:
How to insert strings containing slashes with sed? [duplicate]
(11 answers)
Closed 5 years ago.
i need a quick command (linux or windows) to replace every \\ with a /, and all tries with sed failed because of the /.
(I already tried find . -name '*.*' -exec sed -i 's/\\///g' {} \;, but i think it failed with the "/".
find . -name '*.*' -type f -exec sed -i 's:\\\\:/:g' {} \;
You need to escape each backslash, and using a colon or comma as separators is generally recommended when making replacements with forward-slash. However, escaping the forward slash works too:
find . -name '*.*' -type f -exec sed -i 's/\\\\/\//g' {} \;
As pointed out in comments the OS module is probably what you really need to look at.
Edit: thanks to #tripleee for reminding me of the -type f line, which limits it to files, rather than including the current directory.
Also, I copied the syntax *.* from the OP but in general it isn't helpful. * alone is usually what you want, since files aren't guaranteed to have a dot in their name. Assuming you were happy to include files not containing a dot, the simplest thing to do here is have no -name at all:
find . -type f -exec sed -i 's:\\\\:/:g' {} \;

Use of "{}" and "\;" in sed command [duplicate]

This question already has answers here:
Unix find command, what are the {} and \; for?
(5 answers)
Closed 6 years ago.
I've been googling this, but although I see people using them, I see no explanation for it. I've also tried "find and sed" searches, but again no explanation on these. The sed man and other sed guides out there also don't include it.
Now, I'm using the find command to find several files and then using sed to replace strings whithin the files. I believe that these "{}" and "\;" at the end of the sed are what allows sed to take each file name from find and search through its text. But I'd rather not guess and know for sure what they are and why they're there. Here's my current command:
output=$(find . -type f -name '*.h' -o -name '*.C' -o -name '*.cpp' -o -name "*.cc" -exec sed -n -i "s/ARG2/ARG3/g" {} \;)
I'm also concerned that the ";" at the end may not be necessary since I'm wrapping it also and throwing it into a variable. Could someone clarify what those curlies and backslash are doing and whether I need them?
EDIT: It turns out that they're properties of find -exec, not sed. So I've been looking in the wrong place. Thanks!
find has two versions of the -exec action:
-exec ... {} +
...runs the command ..., with as many filenames from the results as possible added at the end.
-exec ... {} ';'
...runs the command ... once per file found, with the filename substituted in place of the {} sigil; it's not mandatory that the sigil be at the end of the line in this usage.
Thus, either a + or ; needs to be passed as a literal argument to find for it to accept the action as valid.

Can't scape backslashes with sed

I'm trying to find \STRING1\ and replace it with \STRING2\ (mind the backslashes)
I tried the following:
find ./ -type f -exec sed -i "s/\\STRING1\\/\\STRING2\\/g" {} \;
It didn't work and I got this error: sed: -e expression #1, char 21: unterminated `s' command
I searched the web and people recommend adding two backslashes to any backslash I'd like to search and/or replace. So I tried this:
find ./ -type f -exec sed -i "s/\\\STRING1\\\/\\\STRING2\\\/g" {} \;
I got no errors this time, but it didn't do anything. What's the issue?
Use single quotes:
> echo "some text\STRING1\ and some more \STRING1\andeven more" | sed 's/\\STRING1\\/\\STRING2\\/g'
some text\STRING2\ and some more \STRING2\andeven more
If you want to quote your sed command with double quotes, then you have to use quadruple backslashes to get a single literal backslash in the pattern:
find ./ -type f -exec sed -i "s/\\\\STRING1\\\\/\\\\STRING2\\\\/g" {} \;
This is because backslash is a live metacharacter for double-quoted shell strings, so the shell cuts the number of backslashes in half and then so does sed. Alternatively, use single quotes as suggested in the other answer.
You need to use a single quoted string.
If you use double quotes, the string is preprocessed by your shell and sed receives only single backslashes.

What's the proper escaping of the following string for find and replace?

I'm trying to use the following instructions
http://www.brunolinux.com/02-The_Terminal/Find_and%20Replace_with_Sed.html
To replace all occurrences of
<BASE href="file://C:\Users\J\Documents\Personal\J\">
with nothing. I have tried
find . -type f -exec sed -i 's/<BASE href=\"file:\/\/C:\\Users\\J\\Documents\\Personal\\J\\">//g' {} \;
But it's not working likely because something is wrong with escaping characters. What have I done wrong?
Changing the substitution delimiter helps a lot:
find . -type f -exec sed -i \
's!<BASE href="file://C:\\Users\\J\\Documents\\Personal\\J\\">!!g' {} \;
try with this:
s/\<BASE href\="file:\/\/C:\\Users\\J\\Documents\\Personal\\J\\\"\>//g
or try with perl with the same same command i.e.,
instead of sed -i use perl -pi

Resources