perl: 문자열을 새 줄(개행 문자)을 포함하는 변수로 바꿉니다.

perl: 문자열을 새 줄(개행 문자)을 포함하는 변수로 바꿉니다.

메타문자가 포함된 편집을 하고 싶습니다. 여기https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliously-with-sed해결책 중 하나는 via perlwith s\Q ... \E(허용되는 답변의 거의 끝 부분)입니다. 여러 스레드를 처리한다고 알려져 있지만 다음과 같습니다.

echo 'a-b' > a.txt;from='-';to='\n';perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="$to" a.txt
a\nb
echo 'a-b' > a.txt;from='-';to='\n';perl -s -0777 -pe 's/\Q$from\E/\n/' -- -from="$from" -to="$to" a.txt
a
b

변수를 통해 자체에 쓰는 경우에만 개행으로 바꿀 수 있지만 s어떤 이유로 작동하지 않습니다. 웹에서 검색해봐도 답이 안나오네요. 변수를 사용하여 작동하게 하려면 어떻게 해야 합니까 \n?

\nPS 변수는 길이에 제한이 없고 메타 문자를 포함할 수 있습니다. 모든 메타 문자는 개행 문자로 대체되는 하나의 특정 문자 시퀀스(예:)를 제외하고 문자 그대로 사용됩니다.

답변1

문제는 올바른 접근 방식에 관한 것이 아니라 Perl다음에 관한 것입니다 shell.

echo 'a-b' > a.txt
from='-'
to=$'\n' # <<< look at this
perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="$to" a.txt

산출

a
b

답변2

변수를 전처리하여 두 단계로 이 작업을 수행하는 방법을 찾은 것 같습니다.

to="$(printf "%s" "${to}" | perl -pe 's/\Q\n\E/\n/g')"

놀랍게도 이는 단일 기호(개행) 대체에는 작동하지 않지만 더 긴 문자열에는 작동합니다.

echo 'a-b' > a.txt;from='-';to='\n';to="$(printf "%s" "${to}" | perl -p -e 's/\Q\n\E/\n/g')";perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="${to}" a.txt
ab
echo 'a-b' > a.txt;from='-';to='\nd';to="$(printf "%s" "${to}" | perl -p -e 's/\Q\n\E/\n/g')";perl -s -0777 -pe 's/\Q$from\E/$to/' -- -from="$from" -to="${to}" a.txt
a
db

이제 더 긴 문자열만 있는데 왜 단일 기호에 대해 실패하는지 궁금합니다.

다음과 같이 파일에서 변수 할당을 읽을 때 작동합니다.

itext="${line}"
itext="$(printf "%s" "${itext}" | perl -p -e 's/\Q\n\E/\n/g')"
while read -r line; do
    otext="${line}"
    otext="$(printf "%s" "${itext}" | perl -p -e 's/\Q\n\E/\n/g')"
    perl -s -0777 -pi -e 's/\Q$itext\E/$otext/' -- -itext="${itext}" -otext="${otext}" "${file_to_edit}"
done < "${file_with_edits}"

관련 정보