다음과 같이 PHP 파일의 코드 블록을 자동으로 주석 처리하고 싶습니다.
원래 블록:
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
새로운 주석 블록:
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
따라서 이 줄을 두 개의 파일에 넣고 sed를 사용하여 자동으로 교체를 수행하겠습니다. 그런데 인터넷으로 검색한 결과 겨우 찾았습니다.sed를 사용하여 문자열을 파일 내용으로 대체그리고sed - 문자열을 파일 내용으로 교체, 즉 소스 또는 대상 스키마만 하나의 파일에 있고 나머지는 온라인 파일에 있음을 의미합니다. 그러나 파일에는 둘 다의 샘플이 없습니다.
그렇다면 교체하는 방법은 무엇입니까? sed를 사용해야 할까요, 아니면 awk를 사용해야 할까요?
답변1
sed
이 메소드 sed
는 리터럴 문자열을 이해하지 못 하므로 사용하지 마십시오 (참조sed를 사용하여 정규식 메타문자를 안정적으로 이스케이프하는 것이 가능합니까?), 그러한 도구를 사용하여 awk
리터럴 문자열을 이해하는 것이 실제로 가능합니다 .
GNU를 사용한 awk
다중 문자 RS
합계 ARGIND
:
$ awk -v RS='^$' -v ORS= '
ARGIND < 3 { a[ARGIND]=$0; next }
s = index($0,a[1]) {
$0 = substr($0,1,s-1) a[2] substr($0,s+length(a[1]))
}
{ print }
' old new file
this is
the winter
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
of our
discontent
또는 다음 중 하나를 사용하십시오 awk
.
$ awk '
FNR == 1 { a[++argind]=$0; next }
{ a[argind] = a[argind] ORS $0 }
END {
$0 = a[3]
if ( s = index($0,a[1]) ) {
$0 = substr($0,1,s-1) a[2] substr($0,s+length(a[1]))
}
print
}
' old new file
this is
the winter
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
of our
discontent
위의 내용은 다음 입력 파일을 사용하여 실행되었습니다.
$ head old new file
==> old <==
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
==> new <==
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
==> file <==
this is
the winter
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
of our
discontent
답변2
patch
이러한 목적으로 이 유틸리티를 사용하는 것이 좋습니다 .
diff
1. 명령을 사용하여 패치 파일을 만듭니다.
두 개의 파일이 있고 그 중 하나에 교체하려는 블록이 포함되어 있다고 가정해 보겠습니다.
$ cat toreplace.txt
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
다른 하나에는 교체하려는 블록이 포함되어 있습니다.
$ cat replacewith.txt
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/
그들 사이에 상황에 따른 차이를 만들고 콘텐츠를 패치 파일에 넣습니다.
$ diff -c toreplace.txt replacewith.txt > patchfile
$ cat patchfile
*** toreplace.txt 2024-03-17 12:12:31.073270945 +0200
--- replacewith.txt 2024-03-17 12:12:45.276887865 +0200
***************
*** 1,4 ****
--- 1,7 ----
+ /* For the production version, the following codelines are commented
+ out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
+ */
2. 패치 적용
이제 이것을 원본 파일로 간주하십시오.
$ cat myfile
line before 1
line before 2
line before 3
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
line after 1
line after 2
line after 3
이전에 생성한 파일을 사용하여 patch
변경하려는 파일에 대해 명령을 실행할 수 있습니다.patchfile
$ patch -cb myfile patchfile
patching file myfile
Hunk #1 succeeded at 4 (offset 3 lines).
- 깃발이
-c
도착하다-c
"패치 파일을 상황에 따른 차이로 해석합니다(또는 옵션이 지정된 경우 유틸리티 차이점의 출력-C
).".- 없기 때문에 엄격하게 요구되는 것은 아닙니다." 유틸리티는 또는 옵션에 의해 재정의
patch
되지 않는 한 차이 목록의 유형을 결정하려고 시도해야 합니다 . "-c
-e
-n
- 없기 때문에 엄격하게 요구되는 것은 아닙니다." 유틸리티는 또는 옵션에 의해 재정의
- 옵션
-b
은 다음과 같습니다"차이점을 적용하기 전에 수정된 각 파일의 원본 내용 사본을 접미사 가 추가된 동일한 이름의 파일에 저장하십시오.orig
."- 백업을 생성하지 않으려면 이 플래그를 제거할 수 있습니다.
3. 검증
이제 원본 파일을 패치된 파일과 비교해 보세요.
$ diff -c myfile{.orig,}
*** myfile.orig 2024-03-17 13:00:24.936142831 +0200
--- myfile 2024-03-17 13:13:48.882669202 +0200
***************
*** 1,10 ****
--- 1,13 ----
line before 1
line before 2
line before 3
+ /* For the production version, the following codelines are commented
+ out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
+ */
line after 1
line after 2
line after 3
답변3
sed -e '1s/.*/\/* For the production version, the following codelines are commented\nout\n&/g' -e '$s/.*/&\n*\//g'filename
output
/* For the production version, the following codelines are commented
out
// Enable all errors
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(E_ALL);
*/