sed를 사용하여 C 스타일 주석 제거

sed를 사용하여 C 스타일 주석 제거

저장소의 모든 파일에서 특정 특징적인 한 줄 C++ 주석을 제거해야 합니다. 코드는 다음과 같습니다.

some_code
// characteristic_comment_to_delete
some_more_code // another_comment
another_line_with_code // characteristic_comment_to_delete
even_more_code

결과적으로 나는 이것을 얻고 싶습니다 :

some_code
some_more_code // another_comment
another_line_with_code
even_more_code

나는 sed 명령을 사용하여 내가 원하는 만큼 좋은 결과를 얻었습니다.

$ sed -i -e 's&// characteristic_comment_to_delete.*&&g' some_file.cpp
some_code

some_more_code // another_comment
another_line_with_code
even_more_code

불행하게도 이러한 빈 줄을 남겨두는 것은 허용 가능한 해결책이 아니므로 전체 줄을 삭제하도록 명령을 어떻게든 개선해야 하지만 이 특정 주석을 제거한 후에만 공백으로 남겨 두어야 합니다.

편집: 분명히 이 명령을 루트로 실행하고 있지 않습니다. 이에 따라 프롬프트가 변경되었습니다. 또한 모든 댓글을 삭제하고 싶지 않아 내 주제가 다른 스레드와 중복되는 것 같지 않습니다.

답변1

Sed에는 d전체 줄을 삭제하는 명령이 있습니다. (비)구분 기호를 사용할 수도 있지만 /처음 사용할 때 이스케이프해야 합니다 \. 그래서 당신은 다음과 같은 것을 할 수 있습니다

$ sed -e '\#^// characteristic_comment_to_delete$#d' -e 's#// characteristic_comment_to_delete.*##' file
some_code
some_more_code // another_comment
another_line_with_code 
even_more_code

먼저 전체로 구성된 행을 제거한 // characteristic_comment_to_delete다음 나머지 일치 항목을 바꿉니다.

( sed 대체 연산자와의 혼동을 피하기 &위해 귀하의 것을 변경했습니다 ).#&

답변2

GNU 사용 sed:

sed 's|\s*// characteristic_comment_to_delete.*||;T;/./!d'

TGNU 확장입니다나뭇가지이전 s교체가 성공적이지 않은 경우. 따라서 주석이 제거되지 않으면 분기하고 /./!d다음 주석을 건너뜁니다(문자가 하나도 포함되지 않은 줄을 제거합니다).

표준 동등:

sed '\/[[:space:]]*\/\/ characteristic_comment_to_delete.*/{s///;/./!d;}'

또는:

sed 's|[[:space:]]*// characteristic_comment_to_delete.*||
     t 1
     b
     :1
     /./!d'

둘 다 교체가 성공한 경우에만 빈 줄을 억제합니다.

답변3

AWK 솔루션을 수락하는 경우:

awk -F "[   ]*//[   ]*characteristic_comment_to_delete.*" '$1 != "" { print $1; }' some_file.cpp

참고: 이 패턴에는 대괄호 사이에 공백과 탭이 포함되어 있습니다 [ ].

이 솔루션은 주석 패턴이 포함된 문자열 리터럴을 올바르게 처리하지 않습니다.
char text[] = "// characteristic_comment_to_delete bla bla";

답변4

특정 댓글을 제거하는 사소한 작업이 예상보다 훨씬 복잡해졌지만 효과가 있는 솔루션을 찾았고 이를 여러 개의 개별 명령으로 분할했습니다. 주요 문제는 다음과 같은 줄이 있다는 것입니다.

another_line_with_code // characteristic_comment_to_delete#xA;more_code // characteristic_comment_to_delete // characteristic_comment_to_delete

#xA;는 개행 문자이지만 파일이 작성되는 방식은 sed에서 한 줄로 처리됩니다.

이론적으로는 좋은 정규식에도 불구하고 sed가 너무 욕심이 많다는 사실을 피할 수 없기 때문에 Perl을 사용해야 합니다.

주석만 포함된 줄을 제거할 수 있는 최종 솔루션은 다음과 같습니다("d" 매개변수를 알려준 Steeldriver 덕분에 저는 이에 대해 몰랐습니다).

$ find . -type f -print0 | xargs -0 sed -i -e '\#^// characteristic_comment_to_delete\s*$#d'

그리고 인라인 주석을 제거합니다.

$ find . -type f -print0 | xargs -0 perl -pi -e 's|\s*// characteristic_comment_to_delete\s*
||g'

+

$ find . -type f -print0 | xargs -0 perl -pi -e 's|
// characteristic_comment_to_delete\s*||g'

+

$ find . -type f -print0 | xargs -0 perl -pi -e 's|\s*// characteristic_comment_to_delete\s*||g'

이는 단 두 개의 명령으로 쉽게 줄어들 수 있으며 단일 명령으로 모든 사례를 캡처할 수도 있지만 위의 작업이 완료됩니다. 다들 감사 해요!

관련 정보