sed - shell script to replace a keyword in a file with the contents of another file
2014-07
I'm to create a .sh to replace a specific keyword in a file using the contents of an other file.
- template.html contains a unique string "PLACEHOLDER"
- it must be replaced with the contents of file "contents.html"
Sed can be used to replace the keyword:
value="hello superuser"
sed -e "s/__PLACEHOLDER__/${value}/g" template.html > page.html
So I tried the following:
value=$(<contents.html)
sed -e "s/__PLACEHOLDER__/${value}/g" template.html > page.html
And get the following error message: unescaped newline inside substitute pattern
How to handle this sort of situation please?
Thanks!
With bash, you could write:
templ=$(<template.html)
value=$(<contents.html)
echo "${templ//__PLACEHOLDER__/$value}" > page.html
This is because "contents.html" contains multiple lines, and the newline characters have to be converted into \n
before feeding to sed
.
For example if "contents.html" contains
Line 1
Line 2
Line 3
You will need to change it to `Line 1\nLine2\nLine3" before using it as the substitute pattern.
I changed your script as:
value=$(sed ':a;N;$!ba;s/\n/\\n/g' contents.html)
sed -e "s/__PLACEHOLDER__/${value}/g" template.html > page.html
The first line reads "contents.html" and replace newline character with \n
. (Credit to this thread)
Given the following find command: find . | xargs grep 'userTools' -sl
How can I use sed on the results of that command?
output:
./file1.ext
./file2.ext
./file3.ext
I am assuming that you want to perform some sed
operation on the contents of each of the files rather than on the list of file names since you seem to know how to do that already. The answer depends in part on the version of sed
you have available. If it supports the -i
option (edit files in place), you could use xargs
again like this:
find . | xargs grep 'userTools' -sl | xargs -L1 sed -i 's/this/that/g'
If your sed
doesn't have the -i
option, you could do this instead:
find . | xargs grep 'userTools' -sl | while read file
do
sed 's/this/that/g' "$file" > tmpfile
mv tmpfile "$file"
done
find . -print0 | xargs -0 grep -slZ 'userTools' | xargs -0 sed -i 's/foo/bar/'
or
find . -print0 | xargs -0 sed -i '/userTools/ s/foo/bar/'
or
ack -l --print0 'userTools' | xargs -0 sed -i 's/foo/bar/'
find \Path_where_files_are -type f -name 'file_type' -exec sed -e 's/"text_to_be_changed"/"text_to_be_changed_to"/' {} +