sed는 인라인 주석을 제거합니다.

sed는 인라인 주석을 제거합니다.

js 파일에서 주석을 제거하는 간단한 bash 스크립트가 있습니다.

#!/bin/bash
sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' $1 >> stripped.js

인라인 주석을 제외하면 거의 완벽합니다.

// file-to-be-stripped.js
...
...
const someVar = 'var' // this comment won't be stripped
// this comment will be stripped

인라인 댓글을 제거하려면 무엇이 빠졌나요?

고쳐 쓰다:

정말 이상한 점은 온라인 bash 쉘을 사용하여 예제를 시작했는데 완벽하게 실행되었다는 것입니다! 그러나 정확히 동일한 코드를 로컬에서 실행하면 인라인 코드가 제거되지 않습니다! ? 왜/어떻게 이런 일이 발생하는지 아시나요? 나는 분명히 뭔가를 놓치고 있습니다 ... 매우 이상합니다.

업데이트된 코드는 다음과 같습니다.

내 스크립트: Stripper.sh

#!/bin/bash
sed -E -e 's:(\s+(//|#)|^\s*(//|#)).*$::; /^$/d' $1 > "stripped.${1}"

내 테스트 파일: test.js

// testies one
const testies = 'two'
console.log(testies) // three
// testies FOUR!?
console.log('Mmmmm toast') // I won't be stripped of my rights!

그런 다음 실행합니다. ./stripper.sh test.js출력은 다음과 같습니다.

const testies = 'two'
console.log(testies) // three
console.log('Mmmmm toast') // I won't be stripped of my rights!

정확히 동일한 코드가 로컬에서 실행되지만 sed의 전체 줄이 다음과 같이 주석 처리되는 이유에 대한 아이디어가 있습니다.온라인 bash 통역사(안타깝게도 내 쉘에 대한 정확한 링크는 bit.ly 링크이기 때문에 공유할 수 없습니다. 여기서는 분명히 "아니요"입니다.) 이것이 예상대로 작동합니까?

답변1

POSIXly에서는 다음과 같이 합니다.

sed '
  s|[[:blank:]]*//.*||; # remove //comments
  s|[[:blank:]]*#.*||; # remove #comments
  t prune
  b
  :prune
  /./!d; # remove empty lines, but only those that
         # become empty as a result of comment stripping'

GNU를 사용하면 sed이를 다음과 같이 단축할 수 있습니다.

sed -E 's@[[:blank:]]*(//|#).*@@;T;/./!d'

#things이 내용은 기꺼이 제거될 것이며 //things다음과 같은 주석이 아니라는 점에 유의하십시오 .

const url = 'http://stackexchange.com';
x = "foo#bar";

내부 따옴표를 무시 #하려면 //다음을 수행하십시오.

perl -ne 'if (/./) {
   s{\s*(?://|#).*|("(?:\\.|[^"])*"|'"'(?:\\\\.|[^'])*'"'|.)}{$1}g;
   print if /./} else {print}'

다음과 같이 입력하면:

#blah
// testies one
const testies = 'two';
console.log(testies) // three

const url = 'http://stackexchange.com';
x = "not#a comment";
y = "foo\"bar" # comment
y = 'foo\'bar' # it's a comment

그것은 다음을 제공합니다:

const testies = 'two';
console.log(testies)

const url = 'http://stackexchange.com';
x = "not#a comment";
y = "foo\"bar"
y = 'foo\'bar'

#(이 파일의 실제 언어에 적응해야 할 수도 있습니다. node.js로 시작하는 첫 번째 줄 을 제외하고 JavaScript가 주석을 지원하는지 모르겠습니다 #!.)

답변2

sed -e '/^\/\//d' -e 's@\(.*\)[[:blank:]]\{1,\}//.*@\1@' your_file

이 sed 명령은 주석으로 시작하는 줄을 제거하고, 인라인 주석의 경우 주석에서 줄 끝까지 코드를 구분하는 공백의 모든 내용을 제거합니다. POSIX(GNU 확장을 사용하지 않음)이며 OP의 원래 예와 가독성을 기반으로 이 버전은 //주석만 지원합니다(자세한 내용은 아래 참조).

세부 사항

sed호출에는 "패턴 일치 시 제거" 및 교체라는 두 가지 sed 명령이 포함됩니다.

전자는 입니다 /^\/\//d. 이 패턴은 ^\/\/두 개의 슬래시(예: "//foo bar")로 시작하는 행과 일치합니다. 이 줄은 삭제되고 다음 줄이 즉시 도입됩니다(즉, 교체를 건너뜁니다).

교체할 패턴은 입니다 \(.*\)[[:blank:]]\{1,\}//.*. 참고: 구분 기호에 필요한 일부 문자 이스케이프를 @방지하기 위해 구분 기호로 사용하고 있습니다 ./

  • \(.. \)- 일치하는 모든 항목을 역참조로 사용할 수 있습니다.
  • .*- 대체 부분에서 0개 이상의 문자(개행 문자를 제외한 모든 문자)와 일치합니다. \(주변 합계 덕분에 여기서 일치하는 모든 문자를 참조할 수 있습니다 \).
  • [[:blank:]]- 공백 문자
  • \{1,\}- 앞에 있는 하나 이상의 항목과 일치합니다( [[:blank:]]이 경우).
  • //- 두 개의 슬래시와 일치합니다(즉, 주석의 시작 부분).
  • .*- 위와 동일하나 역참조로 사용할 수 없음

교체 부분은 \1첫 번째 역참조, 즉 .*이전 역참조 와 일치하는 항목을 바꾸는 것을 의미합니다 [[:blank:]].

따라서 제가 설명한 대로 작동합니다. 인라인 주석의 경우 주석과 줄 끝까지 코드를 구분하는 공백에 있는 모든 항목을 제거합니다.

'#' 논평

GNU sed 핸들을 사용하여 주석을 추가하면 #대체 //항목으로 대체됩니다 (#|//)(또는 필요한 경우 이스케이프 처리 \(#\|\/\/\)). 그러나 POSIX 방식으로 이를 수행하는 것은 대체가 지원되지 않기 때문에 훨씬 더 장황합니다. 분명히 기존 sed 명령을 반복하여 이 작업을 수행할 수 있습니다 #. 더 좋은 점은 더 깔끔한 접근 방식을 보여주는 답변이 게시되어 있다는 것입니다. 어쨌든 여기서는 해결책을 반복하지 않겠습니다.

편집하다:

오랫동안 이것을 다시 방문하면서 나는 교체가 필요한 것보다 더 복잡하다는 것을 깨달았고 주석에서 지적한 것처럼 (예: "something // foo // bar" ..only "//bar"는 삭제).

나는 이것이 우리에게 필요한 것이라고 믿습니다...

sed -e '/^\/\//d' -e 's@[[:blank:]]\{1,\}//.*@@' your_file

즉, 교체 부분은 "첫 번째 스페이스-슬래시-슬래시가 발생할 때 이전 텍스트를 유지하면서 해당 항목과 그 뒤의 모든 항목을 삭제합니다"를 의미합니다.

답변3

이를 사용하여 스타일 주석 뿐만 아니라 스타일 주석을 GNU sed필터링하는 작은 파서 코드를 작성할 수 있습니다 .C++//sh#

구조를 모듈화하고 확장 가능하게 만들기 위해 쉘 변수에 정의되고 적절하게 참조되는 고정 정규식을 사용합니다.

이 코드를 sed사용하면 빈 줄을 전달할 수 있습니다. 그런 다음 줄에서 균형이 맞지 않는 큰따옴표를 찾습니다. 균형이 맞춰질 때까지 다음 줄을 계속 잡아냅니다. 이는 따옴표가 여러 줄로 넘치도록 하기 위한 것입니다.

작은 따옴표에도 마찬가지입니다.

다음으로, 후행 백슬래시로 식별되는 연속된 줄을 찾습니다.

마지막으로 우리는 인용된 단어나 주석이 아닌 단순한 단어를 계속 건너뜁니다.

이 변환 후에 아무것도 남지 않으면 이를 삭제하고 OTW는 즉시 decommentified해당 행을 표준 출력으로 인쇄합니다.

bash추신: 큰따옴표 안의 문자를 억제할 수 없는 명령줄의 오류를 해결하기 위해 sed -e ...에서 작은따옴표와 큰따옴표를 혼합하여 !작은따옴표로 묶었습니다.

# symbol names
q=\' Q=\"
d=\$ b=\\
B=$b$b

# construct regexes using symbolic names
single_quotes_open="$q[^$b$q]*($B.[^$b$q]*)*$d"
single_quoted_word="$q[^$b$q]*($B.[^$b$q]*)*$q"
double_quoted_word="$Q[^$b$Q]*($B.[^$b$Q]*)*$Q"
double_quotes_open="$Q[^$b$Q]*($B.[^$b$Q]*)*$d"
quoted_word="$double_quoted_word|$single_quoted_word"

# decomment a c++ file
sed -Ee '
   /\S/!b'"
   :a;/(^|\s)$double_quotes_open/{N;ba;}
   :b;/(^|\s)$single_quotes_open/{N;bb;}
   :c;/$B$d/{N;bc;}
   s_\s*(//|#).*|($quoted_word|.)_\2_g
   "'/\S/!d
' c_file

답변4

소스 파일에서 주석을 제거하려면 내 comcat도구를 사용해 보세요. 최신 1박 버전 이용 가능GitHub에서.

  • 댓글만 표시하거나 댓글을 제외한 모든 항목을 표시할 수 있습니다.
  • 이것은 매우 초기 프로젝트이므로 일부 버그가 예상됩니다.

나는 이것이 에 관한 질문이라는 것을 알고 있습니다 sed. 이 답변이 유용하지 않다고 생각되면 삭제해도 됩니다.

부인 성명: 저는 comcat의 관리자입니다.

관련 정보