Skip to main content
Typo.
Source Link
user232326
user232326
#!/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 
Source Link
user232326
user232326

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.

  1. 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?
  2. Quote your variables, echo $line is wrong. Use: echo "$line".
  3. Modify the value of $line and print it only once.
  4. Since there will be only one echo "$line" we may as well do it for the whole loop.
  5. Use ; to place the do's.
  6. Why do you have a dot in your first regex? To match a dot you need \.
  7. You can not use a s/// if the text is going to contain /. Use s@@@, for example.
  8. As you are using a flag of I (s///I) you must use the GNU sed, are you?
  9. In sed BRE there is no alternation |. Only in GNU sed you could use \|.
  10. Please reduce the number of regexes as much as possible, each one is a potential source of misinterpretations.
  11. 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.