텍스트 파일이 있고 에 포함된 (여러 줄) 문자열을 에 포함된 다른 문자열로 바꾸고 싶다고 가정해 보겠습니다 text.txt
. 어떻게 해야 합니까? (저는 정규식을 사용하고 싶지 않습니다. 실제로는 에 포함된 문자열을 에 포함된 텍스트로 바꾸고 싶습니다.before.txt
after.txt
before.txt
after.txt
text.txt
다음에서 제안된 방법을 사용하고 싶습니다. https://unix.stackexchange.com/a/26289/288916
나는 시도했다:
perl -i -p0e 's/`cat before.txt`/`cat after.txt`/se' text.txt
그러나 내가 완전히 바보가 아니고 사소한 일을 망치지 않는 한, cat이 있는 파일에서 찾을 문자열을 로드하도록 이것을 확장할 수는 없습니다.
아마도 탈출에 문제가 있는 것 같습니다. 파일에는 before.txt
다음과 같은 항목이 포함되어 있습니다 /[]"
.
@ilkkachu에게 감사드립니다. 다음을 시도했습니다.
perl -i -0 -pe '$b = `cat before.txt`; $a = `cat after.txt`; s/\Q$b\E/$a/s\' text.txt
, 하지만 여전히 작동하지 않습니다. 이전의 문자열이 문자열을 교체할 전체 줄과 정확히 일치하는지 확인하여 한 인스턴스에서 작동하도록 만들었습니다. 하지만 줄 시작 부분에 없는 문자열을 바꾸는 것처럼 작동하지 않습니다. 예: text.txt
파일에 다음이 포함되어 있습니다:
Here is
some text.
before.txt
포함하다:text
after.txt
포함하다:whatever
기회 없음.
답변1
perl -i -p0e 's/`cat before.txt`/`cat after.txt`/se' text.txt
여기에서는 작은따옴표 안에 백틱이 있으므로 쉘은 이를 처리하지 않지만 Perl은 이를 있는 그대로 봅니다. 또, 펄반품백틱은 인용 형식으로 지원되지만 에서는 사용됩니다 s///
.
Perl 명령줄에서 또는 를 사용하는 한 -0
여러 줄 모드를 사용하는 것은 문제가 되지 않습니다 . -0777
( -0
텍스트 파일에는 없는 NUL 문자로 줄을 구분하여 -0777
전체 파일을 한 번에 읽습니다.)
큰따옴표를 사용하여 이를 수행할 수 있지만 이렇게 하면 Perl 스크립트에서 파일 내용이 직접 확장되며 모든 특수 문자는 스크립트의 일부로 간주됩니다. 단일 슬래시로 인해 s///
연산자가 종료되고 문제가 발생합니다.
대신 Perl이 파일을 읽도록 하십시오:
perl -i -0 -pe '$b = `cat before.txt`; $a = `cat after.txt`; s/$b/$a/s' text.txt
여기서의 내용은 before.txt
여전히 정규식으로 처리됩니다. 중지하려면 s/\Q$b\E/$a/s
대신 사용하세요.
나는 당신이 e
그 플래그를 사용하고 싶지 않을 것이라고 생각합니다 s///
. 이는 대체가 Perl 표현식으로 처리되도록 합니다(이것은 쉘이 파일 내용을 Perl 명령줄로 확장하도록 허용하는 경우에만 실제로 중요합니다).
후자의 예에는 평소와 같이 개행 문자를 나타내는 some text.\n
in text.txt
및 text\n
in 이 있습니다 . 파일이 Perl에 로드되면 있는 그대로 가져오므로 마지막 개행 문자 도 중요합니다. 다른 파일에는 개행 앞에 점이 있고 다른 파일에는 점이 없으므로 일치하지 않습니다.before.txt
\n
before.txt
. 다음을 사용하여 가능한 후행 개행 문자를 제거할 수 있습니다 chomp $b;
파일을 로드한 후 가능한 후행 줄 바꿈을 제거할 수 있습니다$b =~ s/\n$//;
.
$ perl -0 -pe '$b = `cat before.txt`; $a = `cat after.txt`; $b =~ s/\n$//; $a =~ s/\n$//; s/$b/$a/s' text.txt
Here is
some whatever.
답변2
작은따옴표 안의 역따옴표는 문자 그대로 처리됩니다. 제공한 예제에서는 이를 큰따옴표로 바꿀 수 있어야 합니다.
백틱도 어떤 이유로 바람직하지 않으므로 여기서는 다음과 같이 변경했습니다.$( )
perl -i -p0e "s/$(cat before.txt)/$(cat after.txt)/se" text.txt
참고: 저는 단지 귀하의 인용 문제를 해결하는 중일 뿐 귀하의 명령이 귀하의 의도를 달성할 것이라는 보장은 없습니다.