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