이것은 이전 질문의 고급 버전입니다(줄을 변경하려고 할 때 매개변수를 Perl에 전달하는 방법은 무엇입니까?) 그랬어요.
이번에는 경로를 전달하려고 시도했지만 Perl 스크립트가 /를 잘못 읽은 것 같습니다.
file.txt의 4번째 줄이 다음과 같다고 가정해 보겠습니다.
path_root_abs = "/path/to/thefile"
작업 디렉토리를 가져와 /path/to/file로 바꾸려면
directory=`pwd`
perl -i -pe "s/(path_root_abs\s=\s\")(.*)(\")/\$1${directory}$3/ if \$. == 4" file.txt
그리고 얻다:
Bareword found where operator expected at -e line 1, near "s/(path_root_abs\s=\s")(.*)(")/$1/scratch"
syntax error at -e line 1, near "s/(path_root_abs\s=\s")(.*)(")/$1/scratch"
Execution of -e aborted due to compilation errors.
유닉스가 스크래치 후의 \를 벌거벗은 단어로 읽는 것을 방지하려면 어떻게 해야 합니까?
답변1
첫 번째 문제는 $directory
대체 연산자( ) s///
의 구분 기호 로도 사용되는 슬래시를 포함한다는 것입니다. 기본적으로 Perl이 보는 것은 다음과 $directory
같습니다 ./home/je_b
perl -i -pe "s/foo//home/jb/ if \$. == 4" file.txt
/
연산자 중 /home
두 번째 로 of 를 사용합니다 . 가장 간단한 해결책은 대신 다른 문자를 사용하는 것입니다./
s///
/
perl -i -pe "s#foo#${directory}#" file.txt
그러나 다른 방법으로 단순화할 수 있습니다. 생각해 보세요:
perl -pe "s#(path_root_abs = \")(.*)#\1${directory}\"# if \$. == 4" file
\s
공백만 일치시켜야 하는 경우에는 필요하지 않으며 공백만 사용하면 됩니다.- Perl의 대체 연산자는 두 가지를 모두 이해하므로
$1
후자\1
를 사용하고 이스케이프를 피하세요. - 캐릭터를 잡아도 소용이 없습니다
"
. 거기에 있다는 것을 알고 있다면 직접 추가하십시오.
pwd
마지막으로 Perl에서 직접 가져올 수도 있습니다 . Perl은 해시를 통해 내보낸 모든 쉘 변수에 액세스할 수 있습니다 %ENV
. 따라서 다음과 같이 할 수 있습니다.
perl -pe 's#(path_root_abs = ").*#$1$ENV{PWD}"# if $.==1' file