#!/bin/ksh test_path=/some/fake/path/ reg1='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)' sed 's@'"$reg2"'@\1"'"$test_path"'"@''s@'"$reg1"'@\1"'"$test_path"'"@' ./original.sas > ./edited.sas #!/bin/ksh test_path=/some/fake/path/ reg1='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)' sed 's@'"$reg2"'@\1"'"$test_path"'"@' ./original.sas > ./edited.sas #!/bin/ksh test_path=/some/fake/path/ reg1='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)' sed 's@'"$reg1"'@\1"'"$test_path"'"@' ./original.sas > ./edited.sas From your original script posted (now edited out):
Why four different regex ?? (well three, reg3 seems to be identical to the sed regex reported in your error line):
reg1='libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}\.[[:alnum:]]\{1,\}[[:space:]]\{1,\}oracle path' reg2='libname[[:space:]]\{1,\}' reg3='\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)' sed1='s/\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)/\2"/some/fake/path/"/I` Problem description
Your whole problem could be reduced to this code:
sourcepath='/random/path/reference/' test_path='/some/fake/path/' echo "LIBNAME somelib \"$sourcepath\"" | sed -n 's@\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)@\1"'"$test_path"'"@p' Which will print LIBNAME somelib "/some/fake/path/".
If the regex doesn't match, nothing gets printed.
Solution script
That leads to write this script:
#!/bin/ksh - test_path=/some/fake/path/ reg1='libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}.[[:alnum:]]\{1,\}[[:space:]]\{1,\}oracle path' reg2='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)' :>./edited.sas while IFS=$' \t\n' read -r line; do newline=$(echo "$line" | sed -n 's@'"$reg2"'@\1"'"$test_path"'"@p') if [ -n "$newline" ]; then line=$newline fi echo "$line" done < ./original.sas >> ./edited.sas A simpler solution, but still ...
Recommended script
But, knowing that a shell is not the best way to edit a file.
Having already reduced the whole script to a sed regex.
We should reduce the script even more to the simpler:
#!/bin/ksh test_path=/some/fake/path/ reg1='\(LIBNAME[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("\(\([^"]\|\\"\)*\)"\)' sed 's@'"$reg2"'@\1"'"$test_path"'"@' ./original.sas > ./edited.sas code issues
There are some issues in your code.
- You claim to need to modify
LIBNAME somelib '/random/path/reference/';, with single quotes. But your code (regex) is trying to match double quotes:LIBNAME somelib "/random/path/reference/";Which is it? - Quote your variables,
echo $lineis wrong. Use:echo "$line". - Modify the value of
$lineand print it only once. - Since there will be only one
echo "$line"we may as well do it for the whole loop. - Use
;to place thedo's. - Why do you have a dot in your first regex? To match a dot you need
\. - You can not use a
s///if the text is going to contain/. Uses@@@, for example. - As you are using a flag of
I(s///I) you must use the GNU sed, are you? - In sed BRE there is no alternation
|. Only in GNU sed you could use\|. - Please reduce the number of regexes as much as possible, each one is a potential source of misinterpretations.
- You can set a new variable to the modified value of line if it match the regex. If the variable is empty, the regex didn't match.
lang-bash