코드 블록이 여러 줄이고 START-END 블록에 빈 줄이 나타날 수 있다는 점을 고려하면 /** START */
using으로 시작하고 끝나는 코드 블록을 탐욕스럽지 않게 제거하는 방법은 무엇입니까?/** END */
sed
START는 한 줄 주석을 표시합니다.
입력하다:
class MyClass {
keepField;
/** START */
deleteField;
/** END */
construct() {
/** START */
this.deleteField = 'delete';
/** END */
this.keepField = 'keep';
/** START */
this.deleteFunc();
/** END */
}
/** START */
deleteFunc() {
this.keepField = 'delete';
if (true) {
console.debug('Line before if statement is empty.');
}
} /** END */
}
산출:
class MyClass {
keepField;
construct() {
this.keepField = 'keep';
}
}
나는 다음 sed '/./{H;$!d} ; x ; s/START.*END//' MyClass.js
과 같이 시도했습니다sed 매뉴얼>다중 라인 기술 섹션.
그러나 위의 명령은 빈 줄이 없고 여러 START-END 블록( 에서와 같이 constructor
)과 빈 코드 줄이 START-END 블록 내부(함수에서와 같이)로 간주되지 않는 경우 deleteFunc
블록에서 탐욕적입니다 .
sed
예를 들어 다른 명령줄 도구를 사용하여 위의 문제를 해결하는 방법에 대해 알고 계시나요 awk
?
START 태그는 블록 주석입니다.
입력하다:
class MyClass {
/**
* same code as above only this time the START block is
* multiline like below.
*/
/**
* START
*/
deleteFunc() {
this.keepField = 'delete';
if (true) {
console.debug('Line before if statement is empty.');
}
} /** END */
}
출력은 다음과 같아야 합니다.
class MyClass {
keepField;
construct() {
this.keepField = 'keep';
}
}
답변1
sed는 간단한 s/old/new/ 작업을 수행하기 위한 훌륭한 도구입니다. 그 외에는 명확성, 효율성, 견고성, 이식성, 유지 관리성 등을 위해 awk를 사용하세요. 예를 들어 POSIX awk를 사용하면 다음과 같습니다.
$ cat tst.awk
{ rec = rec $0 ORS }
END {
while ( match(rec,/\/\*\*[[:space:]*]*END[[:space:]*]*\*\//) ) {
toEnd = substr(rec,1,RSTART+RLENGTH-1)
sub(/(\n[[:blank:]]*)?\/\*\*[[:space:]*]*START[[:space:]*]*\*\/.*/,"",toEnd)
printf "%s", toEnd
rec = substr(rec,RSTART+RLENGTH)
}
printf "%s", rec
}
$ awk -f tst.awk file
class MyClass {
keepField;
construct() {
this.keepField = 'keep';
}
}
class MyClass {
/**
* same code as above only this time the START block is
* multiline like below.
*/
}
POSIX awk가 없는 경우 각각을 [:space:]
to \t\n
및 to로 [:blank:]
변경하면 \t
(각 문자열의 첫 번째 문자는 리터럴 공백 문자임) 모든 awk에서 작동합니다.
위의 코드는 이 입력 파일에서 실행됩니다.
$ cat file
class MyClass {
keepField;
/** START */
deleteField;
/** END */
construct() {
/** START */
this.deleteField = 'delete';
/** END */
this.keepField = 'keep';
/** START */
this.deleteFunc();
/** END */
}
/** START */
deleteFunc() {
this.keepField = 'delete';
if (true) {
console.debug('Line before if statement is empty.');
}
} /** END */
}
class MyClass {
/**
* same code as above only this time the START block is
* multiline like below.
*/
/**
* START
*/
deleteFunc() {
this.keepField = 'delete';
if (true) {
console.debug('Line before if statement is empty.');
}
} /** END */
}
그러나 전체 입력이 한 줄에 있는 병리적인 경우도 고려하십시오.
$ cat file
class MyClass { keepField; /** START */ deleteField; /** END */ construct() { /** START */ this.deleteField = 'delete'; /** END */ this.keepField = 'keep'; /** START */ this.deleteFunc(); /** END */ } /** START */ deleteFunc() { this.keepField = 'delete'; if (true) { console.debug('Line before if statement is empty.'); } } /** END */ }
그리고 위의 스크립트는 이를 올바르게 처리합니다. (시작/끝 문자열이 리터럴 문자열 내부에 있거나 주석 내부에 있을 수 있다는 점을 제외하고는 선언되지 않은 다른 많은 경우도 처리한다고 상상할 수 있습니다. 패턴 일치를 사용하여 상황을 처리할 수는 없습니다.) 우리가 하는 것처럼요):
$ awk -f tst.awk file
class MyClass { keepField; construct() { this.keepField = 'keep'; } }
답변2
GNU 사용sed
$ sed -Ez 's~ +/?\*+ START( \*)?([^*]*\*+)([^\n]*\n[^*]*\*+)? END[^\n]*\n~~g' input_file
class MyClass {
keepField;
construct() {
this.keepField = 'keep';
}
}
class MyClass {
/**
* same code as above only this time the START block is
* multiline like below.
*/
/**
}