문제 설명

문제 설명

SAS 프로그램에서 LIBNAME 문을 바꾸려고 합니다. 수정하고 싶은 줄의 예는 다음과 같습니다.

LIBNAME somelib '/random/path/reference/';

somelib문자열을 그대로 유지하고 '/random/path/reference/'내가 정의한 변수로만 바꾸고 싶습니다 /some/fake/path/(예: 작은따옴표로 묶음).

교체하려고 하면 sed다음과 같은 오류가 발생합니다.

sed: 0602-404 Function s/\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)/\2\"/some/fake/path/"/ cannot be parsed.

파싱할 수 없는 코드는 기본적으로 다음과 같습니다.

test_path=/some/fake/path/

sed 's/\(libname[[:space:]]\{1,\}[[:alnum:]]\{1,\}[[:space:]]\{1,\}\)\("([^"]|\\")*"\)/\2\"'$test_path'"/I'

나는 지금 어찌할 바를 모르고 있다.

답변1

귀하가 게시한 원본 스크립트(현재 편집됨)에서:

정규식이 4개 있는 이유는 무엇입니까? (셋째, reg3은 오류 줄에 보고된 것과 동일한 sed 정규식인 것으로 보입니다):

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`

문제 설명

전체 문제는 다음 코드로 축소될 수 있습니다.

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'

인쇄됩니다 LIBNAME somelib "/some/fake/path/".

정규식이 일치하지 않으면 아무것도 인쇄되지 않습니다.

솔루션 스크립트

그 결과 다음 스크립트가 작성되었습니다.

#!/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

더 간단한 해결책이지만 여전히 ...

추천 스크립트

그러나 셸은 파일을 편집하는 가장 좋은 방법이 아닙니다.
전체 스크립트가 sed 정규식으로 축소되었습니다.

스크립트를 더 간단하게 단순화해야 합니다.

#!/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

코드 문제
코드에 몇 가지 문제가 있습니다.

  1. 작은따옴표를 사용하여 수정해야 한다고 주장합니다 LIBNAME somelib '/random/path/reference/';. 하지만 귀하의 코드(정규식)는 큰따옴표를 일치시키려고 합니다. LIBNAME somelib "/random/path/reference/"; 어느 것입니까?
  2. 변수를 인용하는 것이 echo $line잘못되었습니다. 사용: echo "$line".
  3. 수정된 값은 $line한 번만 인쇄됩니다.
  4. 하나만 있기 때문에 echo "$line"루프 전체에서 이 작업을 수행하는 것이 좋습니다.
  5. ;배치를 위해 do.
  6. 첫 번째 정규식에 점이 있는 이유는 무엇입니까? 필요한 포인트를 맞춰보세요\.
  7. 당신은 할 수아니요s///텍스트를 포함하려면 를 사용하세요 /. s@@@예를 들어 사용합니다.
  8. I( ) 플래그를 사용할 때는 s///IGNU sed를 사용해야겠죠?
  9. sed BRE에는 대체가 없습니다 |. GNU sed로만 사용할 수 있습니다 \|.
  10. 정규식의 수를 최소한으로 유지하십시오. 각 정규식은 오해의 원인이 될 수 있습니다.
  11. 새 변수는 정규식과 일치하는 경우 line의 수정된 값으로 설정될 수 있습니다. 변수가 비어 있으면 정규식이 일치하지 않습니다.

관련 정보