Reputation: 169
I know there are lots of similar questions but, I guess because of the formatting of the search/replace variables they are not working for my situation.
The overall script I am working on will read a text file (using combinations of grep and awk) to create two shell variables, $find and $replace. $find is a single line string containing all manner of characters. $replace is a multiline string containing all manner of characters.
example:
echo "$find"
returns
type result input1 another_input random_input<10> / name
and
echo "$replace"
returns
.TAG name
result input1 random_input / name1
random_input<10> input1 another_input / name2
.NTAG
Now I just need to substitute $find with $replace. I have tried sed and perl but it fails.
Tried (among a lot of other stuff)
perl -e -i.bak "s/$find/$replace/g" text.file
perl -e -i.bak 's,"'$find'","'$replace'",g' text.file
perl -e -i.bak "s|$find|$replace|g" text.file
and
sed -i "s/$find/$replace/g" text.file
My guess is the problems are caused by some character in the string being interpreted as special characters.
Any help is appreciated!
Upvotes: 1
Views: 1144
Reputation: 10039
one way with sed, quick and dirty so not bullet proof like the awk of @Ed Morton
find_sed="$( printf "%s" "${find}" | sed 's/[^0-9(){}]/\\&/g' )"
replace_sed="$( printf "%s" "${replace}" | sed "s/[&\\]/\\/g;s/\n/\\&/g' )"
sed "s/${find_sed}/${replace_sed}/g" YourFile
--posix
with GNU sed), if not posix, adapt [^0-9(){}]
depending your special character that use a escape char for special meaning like \+\n\d\
Upvotes: 0
Reputation: 8412
restructure your variable to read
replace=".TAG name\nresult input1 random_input / name1\nrandom_input<10> input1 another_input / name2\n.NTAG"
or restructure it like this
replace='.TAG name\
result input1 random_input / name1\
random_input<10> input1 another_input / name2\
.NTAG'
Also your delimiter is causing conflict with your variable replace
characters since there are /
in your variable
you can try #
as your delimiter or any other char that is not in your variable
sed "s#$find#$replace#g" text_file
Upvotes: 0
Reputation: 203684
This will work for any values of find or replace:
$ cat file
foo
type result input1 another_input random_input<10> / name
bar
$ awk -v find="$find" -v replace="$replace" 's=index($0,find){$0=substr($0,1,s-1) replace substr($0,s+length(find))}1' file
foo
.TAG name
result input1 random_input / name1
random_input<10> input1 another_input / name2
.NTAG
bar
if find
is always one whole line it can be simplified, e.g. this might be all you need:
$ awk -v find="$find" -v replace="$replace" '$0==find{$0=replace}1' file
foo
.TAG name
result input1 random_input / name1
random_input<10> input1 another_input / name2
.NTAG
bar
Upvotes: 2