I would like to have a shell script to do a find and replace on anything without using regular expressions (regex), that includes all the specials chars such as !@#$%¨&*()?^~]}[{´`>.<,"'
So for example the function would be able to receive two parameters where the 1st will be what I want to find, and the second parameter will be what will be replaced with.
Example 1:
File1:
BETWEEN TO_DATE('&1','YYYY-MM-DD') +1 and TO_DATE('&2','YYYY-MM-DD') +15
First parameter: TO_DATE('&1','YYYY-MM-DD')
Second parameter: TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS')
File1 after calling the function to replace:
BETWEEN TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS') +1 and TO_DATE('&2','YYYY-MM-DD') +15
Example 2:
File2:
This is just a test/2^
Paramter1: test/2^
Paramter1: testing\$2^]'
File2 after calling the function to replace:
This is just a test/2^
The param1 and param2 could be really anything.
I need to use UNIX
OS AIX
it could be KornShell (ksh) using sed or awk. I can not use either perl or Java. I also can not install anything on this server.
I'd use awk and the string functions index() and substr() that don't use patterns
awk -v find="$param1" -v repl="$param2" '{
while (i=index($0,find))
$0 = substr($0,1,i-1) repl substr($0,i+length(find))
print
}' file
I assume that there may be more than one match per line.
testing
$ param1="TO_DATE('&1','YYYY-MM-DD')"
$ param2="TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS')"
$ awk -v find="$param1" -v repl="$param2" '{
while (i=index($0,find))
$0 = substr($0,1,i-1) repl substr($0,i+length(find))
print
}' << END
BETWEEN TO_DATE('&1','YYYY-MM-DD') +1 and TO_DATE('&2','YYYY-MM-DD') +15
END
BETWEEN TO_DATE('&1 23:59:59','YYYY-MM-DD HH@$:MI:SS') +1 and TO_DATE('&2','YYYY-MM-DD') +15
The 2nd test is a bit problematic:
$ param1='test/2^'
$ param2='testing\$2^]'\'
$ awk -v find="$param1" -v repl="$param2" '{
while (i=index($0,find))
$0 = substr($0,1,i-1) repl substr($0,i+length(find))
print
}' <<< "This is just a test/2^"
awk: warning: escape sequence `\$' treated as plain `$'
This is just a testing$2^]'
So you need to pre-process the parameters to escape any backslashes:
$ awk -v find="$(sed 's/\\/&&/g' <<< "$param1")" \
-v repl="$(sed 's/\\/&&/g' <<< "$param2")" \
'{
while (i=index($0,find))
$0 = substr($0,1,i-1) repl substr($0,i+length(find))
print
}' <<< "This is just a test/2^"
This is just a testing\$2^]'
To accomodate Ed's astute point:
param1=foo
param2=_foo_
awk -v find="$(sed 's/\\/&&/g' <<< "$param1")" \
-v repl="$(sed 's/\\/&&/g' <<< "$param2")" \
'
index($0, find) {
start = 1
line = $0
newline = ""
while (i=index(line, find)) {
newline = newline substr(line, 1, i-1) repl
start += i + length(find) - 1
line = substr($0, start)
}
$0 = newline line
}
{print}
' <<END
abcfoodeffooghifoobar
food
blahfoo
no match
END
abc_foo_def_foo_ghi_foo_bar
_foo_d
blah_foo_
no match