sed를 사용하여 C 스타일 주석을 C++ 스타일로 변환

sed를 사용하여 C 스타일 주석을 C++ 스타일로 변환

한 줄의 "C" 스타일 주석을 "C++" 스타일로 변환하려고 합니다. 아래의 "sed"는 나쁘지 않지만, 선행 코드(주석 앞의 코드)에 "/"가 있으면 당연히 실패합니다.

sed -i 's,\(^[^\/]*\)\/\*\([^\*]*\)\*\/[ ]*$,\1\/\/\2,' filename

제가 할 수 있기를 바라는 것은 다음과 같습니다.

... [^\\/\\*] ...

즉, "/*"를 부정하는 것은 물론 작동하지 않지만 몇 시간 동안 검색한 후에도 찾을 수 없습니다.단순한이를 올바르게 수행하는 방법을 설명하십시오.( 이것은 로켓 과학이 아닌 것 같습니다.

예를 들어 다음 문자열은 다음과 같습니다.

blah blah        /* comment */
blah blah / blah /* comment */
blah blah        /* comment */ blah
blah blah / blah /* comment */ blah 

...다음과 같이 변환되어야 합니다.

blah blah        // comment 
blah blah / blah // comment 
blah blah        /* comment */ blah  (this CAN'T be converted)
blah blah / blah /* comment */ blah  (this CAN'T be converted)

...분명히 "C" 주석 뒤에 코드가 있으면 변환이 발생하지 않습니다.

파일 전후를 주의 깊게 시각적으로 비교할 것이므로 텍스트에서 "/*"를 처리할 필요도 없고 여러 줄의 내용을 변환하고 싶지도 않습니다.

나는 이것이 "부정적인" 질문이라고 생각하지만 아마도 다른 방법이 있을 수도 있다는 점에 유의하십시오. "/*" 이전의 모든 항목을 캡처하면 됩니다. 방법은 상관없습니다.

아래 답변을 따라가세요

빌어 먹을! 나는 내가 기본적인 것을 완전히 오해했다는 것을 발견했습니다.

.*/\*

...읽기: "슬래시 별표 뒤에 슬래시 별표가 오는 것을 제외한 모든 것", 그래서 실제로 "neg"를 무료로 얻습니다 :-)

따라서 Barmar보다 한 단계 더 발전했습니다.

sed -i 's,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,' filename

...심지어 이것을 잡을 것입니다:

blah / * blah        /* co / mme * nt */

그리고 출력:

blah / * blah       // co / mme * nt 

계발.

답변1

이 시도:

sed 's,^\(.*\)/\*\([^/]*\)\*/$,\1//\2,'

/포함된 문자가 포함된 주석은 변환되지 않습니다 . 또는 다음을 사용할 수 있습니다.

sed 's,^\(.*\)/\*\(.*\)\*/$,\1//\2,'

같은 줄에 두 개의 주석이 있으면 잘못된 일이 됩니다.

blah blah        /* comment1 */ blah /* comment2 */

로 변환됩니다

blah blah       // comment1 */ blah /* comment2

부정적인 예측을 사용하여 내장된 주석을 테스트할 수 있으므로 PCRE 버전을 사용하는 것이 더 나을 수 있습니다 sed.

또한 ,명령에서 구분 기호로 사용한다는 것은 정규 표현식의 모든 문자를 s이스케이프할 필요가 없다는 것을 의미합니다 /. 이는 /정규 표현식에 /.

답변2

아마도 가장 안전한 접근 방식은 영향을 주지 않으려는 행을 먼저 테스트하고 b일치하는 경우 스크립트를 종료하는 것입니다.

sed '\|\*/.*/\*|b'

*모든 별표가 포함되어 있어 읽기가 약간 어렵지만 기본적으로 /*if가 발생한 후에 */ sed는 스크립트 실행을 종료하고 자동으로 줄을 인쇄한 다음 다음 줄을 당겨서 다음 줄 루프를 시작합니다. 일치하는 줄의 경우 그 뒤에 오는 명령은 실행되지 않습니다.

또 다른 방법은 est를 사용하는 것입니다 . 이는 t성공적인 교체 후 목초지 태그가 제공되지 않으면 b스크립트에서도 동일한 작업을 수행합니다 .bs///

sed 's|/\*|&|2;t'

줄에서 두 번째로 나타나는 패턴을 자신의 패턴으로 바꾸려고 시도하며, 성공하면 같은 방식으로 분기됩니다 b.

그래서...

sed 's|/\*|&|2;s|\*/|&|2;t
     s|/\*\(.*\)\*/ *$|//\1|'

/*... 후행 공백 문자 수에 관계없이 //끝나는 줄의 첫 번째이자 유일한 발생을 대체합니다 . */이는 이전에 발생한 모든 대체에 적용되기 때문에 작동하므로 t둘 중 하나가 t성공 하면 sed분기됩니다.

하지만 저는 C나 C++에 익숙하지 않고 이 경우 무엇을 기대해야 할지 잘 모르기 때문에 여기서 실수를 저지르고 있을 수도 있습니다 . /\*.*\*/.*\*/위의 스크립트는 2만 테스트해야 하거나 2만 b테스트해야 할 수도 있습니다 . 그러나 적어도 나는 이 개념을 더 잘 아는 사람에게 전달할 수 있기를 바랍니다.*//*

답변3

우연히 위의 내용이 필요했지만 여러 줄도 필요했습니다. 그래서 Barmar의 답변을 내 자신의 일부 sed와 병합하여 이를 달성했습니다.

sed -e '/\/\*/,/\*\//{s/^\( *\)\/\*/\1~~/g;s/^\( *\) \*\//\1~~/g;s/^\( *\) \*/\1~~/g;s/~~/\/\//g};s/\*\*/\/\//g;s,^\(.*\)/\*\(.*\)\*/\s*$,\1//\2,'

(그런데 Mac에서는 gsed가 필요합니다. 그렇지 않으면 위의 오류가 발생합니다)

전/후 차이입니다

***************
*** 1,13 ****

! /*
     FOO
!  */

! /*
!  * BAR
!  */

! blah blah        /* comment */
! blah blah / blah /* comment */
  blah blah        /* comment */ blah
  blah blah / blah /* comment */ blah
--- 1,13 ----

! //
     FOO
! //

! //
! // BAR
! //

! blah blah        // comment
! blah blah / blah // comment
  blah blah        /* comment */ blah
  blah blah / blah /* comment */ blah

관련 정보