2010-05-22 3 views
3

는이 같은 헤더 파일이 있습니다python, perl 또는 sed를 사용하여 헤더 파일에서 주석을 추출하는 방법은 무엇입니까?

/* 
* APP 180-2 ALG-254/258/772 implementation 
* Last update: 03/01/2006 
* Issue date: 08/22/2004 
* 
* Copyright (C) 2006 Somebody's Name here 
* All rights reserved. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions 
* are met: 
* 1. Redistributions of source code must retain the above copyright 
* notice, this list of conditions and the following disclaimer. 
* 2. Redistributions in binary form must reproduce the above copyright 
* notice, this list of conditions and the following disclaimer in the 
* documentation and/or other materials provided with the distribution. 
* 3. Neither the name of the project nor the names of its contributors 
* may be used to endorse or promote products derived from this software 
* without specific prior written permission. 
* 
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
* SUCH DAMAGE. 
*/ 

#ifndef HEADER_H 
#define HEADER_H 

/* More comments and C++ code here. */ 

#endif /* End of file. */ 

을 그리고는 "*"각 라인의 시작 파일을 얻을에만 C 스타일 주석의 내용을 추출하고 드롭 할 다음과 같은 내용으로 :

APP 180-2 ALG-254/258/772 implementation 
Last update: 03/01/2006 
Issue date: 08/22/2004 

Copyright (C) 2006 Somebody's Name here 
All rights reserved. 

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions 
are met: 
1. Redistributions of source code must retain the above copyright 
    notice, this list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright 
    notice, this list of conditions and the following disclaimer in the 
    documentation and/or other materials provided with the distribution. 
3. Neither the name of the project nor the names of its contributors 
    may be used to endorse or promote products derived from this software 
    without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
SUCH DAMAGE. 

파이썬, 펄, 나오지도, 또는 유닉스에서 다른 방법으로이 작업을 수행 할 수있는 쉬운 방법을 제안 해주십시오. 바람직하게는 1 라이너로.

답변

5

이 당신을 위해 작동합니다 : 여기

sed -n '/\*\//q; /^\/\*/d; s/^ \* \?//p' <file.h >comment.txt 

는 설명이다 : 나오지 것은 (아시다시피) 적용하는 파일을 통해가는 명령입니다 각 행에 대한 규칙 목록. 각 규칙은 선택기와 해당 선택기가 일치하는 경우에만 해당 행에 적용되는 명령으로 구성됩니다.

첫 번째 규칙에는 선택자 /\*\//이 있습니다. 이것은 정규식 선택자입니다. 문자는 */을 포함하는 모든 행과 일치합니다. 이들 모두는 정규 표현식에서 특별한 의미를 가지기 때문에 백 슬래시 이스케이프해야합니다. (나는이 경우에만 귀하의 경우에 주석의 닫는 라인과 일치하고이 전체 라인을 삭제해야한다고 가정했습니다.) 명령은 q이며 "종료"를 의미합니다. sed가 멈 춥니 다. 일반적으로이 줄을 인쇄하지만, "명시 적으로 지시하지 않으면 인쇄하지 마십시오"라는 의미의 -n 옵션을 제공했습니다.

두 번째 규칙에는 라인 시작 부분에 /* 문자와 일치하는 정규식 선택기 인 선택자 /^\/\*/이 있습니다. 다시 말하지만이 줄에는 주석의 일부가 포함되지 않는다고 가정했습니다. d 명령은 sed에게이 행을 삭제하고 계속 진행하도록 명령합니다.

최종 규칙에는 선택자가 없으므로 이전 명령이 처리가 최종 규칙에 도달하지 않는 한 모든 행에 적용됩니다. 이 마지막 룰의 명령은 대치 명령 인 s/PATTERN/REPLACEMENT/입니다. 행에서 일부 패턴과 일치하는 텍스트를 찾아 대체 텍스트로 바꿉니다. 여기 패턴은 ^ \* \?이며 공백, 별표 및 0 또는 1 공백과 일치하지만 줄의 시작 부분에서만 일치합니다. 그리고 그 대체품은 아무것도 아닙니다. 그래서 sed는 단순히 선행 공백 - 별표 - (공백)을 삭제합니까? 순서. p은 실제로 대체 명령의 플래그로 sed에게 대체 결과를 출력하도록 지시합니다. -n 옵션이 필요합니다.

+0

이것은 "/ *", "*", "* /"의 빈 줄 뒤에 가깝습니다./* 및 */줄은 삭제하고 "*"줄은 공백으로 남겨 두어야합니다. – WilliamKF

+1

BTW,이 마법을 직접 수행 할 수 있도록 명령 줄을 해석하는 방법을 설명하면 도움이 될 것입니다. – WilliamKF

+0

그래, 나도 알아, 그게 내가 작업을 조정할 수 있습니다. 완전한 해결책과 설명이 곧 나옵니다. –

-1
sed -i -r "s/[\/\ ]{1}\*[\/\ ]?//g" YOURFILENAME 

콘텐츠를 유지하면서 파일의 주석을 대체합니다. 이 파일은 YOURFILENAME 파일을 수정합니다. 당신이이 줄에서 -i 제거하지 않으려면

+0

첫 번째 주석 다음에 나오는 모든 C++ 코드가 닫히지는 않습니다. – WilliamKF

+0

또한 원본 파일을 부작용하지 않고 대신 새 파일을 만듭니다. – WilliamKF

+0

printf ("\\ 주석이 아닙니다."); 및 printf ("/ * 어느 쪽도 아니 * /"); – Richard

4

Pyparsing에는 다양한 언어의 주석 형식을 일치시키는 기본 제공 패턴이 포함되어 있습니다. cStyleCommentscanString를 사용하여 소스 파일의 첫 번째 댓글이 나머지 단지 문자열 함수를하게 찾을 수 있습니다 :

c_src = open(c_source_file).read() 

from pyparsing import cStyleComment 
cmt = cStyleComment.scanString(c_src).next()[0][0] 
lines = [l[3:] for l in cmt.splitlines()] 
print '\n'.join(lines) 

scanString, 그래서 첫 번째 주석 처리됩니다 다음 인스턴스로 이동하기 전에 각 경기를 반환하는 생성기입니다.샘플 코드를 사용하면 다음과 같이 반환됩니다.

APP 180-2 ALG-254/258/772 implementation 
Last update: 03/01/2006 
Issue date: 08/22/2004 

Copyright (C) 2006 Somebody's Name here 
All rights reserved. 

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions 
are met: 
1. Redistributions of source code must retain the above copyright 
    notice, this list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright 
    notice, this list of conditions and the following disclaimer in the 
    documentation and/or other materials provided with the distribution. 
3. Neither the name of the project nor the names of its contributors 
    may be used to endorse or promote products derived from this software 
    without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
SUCH DAMAGE. 
+0

이 소프트웨어조차도 기본적인 테스트에는 실패합니다.'printf ("// 주석이 아닙니다!");는 cppCommentStyle에 의해 주석으로 선택되었지만 흥미롭게도 cCommentStyle은 아닙니다. – Richard

+2

여기서 오류는 테스트에 암시 적 지식을 추가했으나 표현식에 추가하지 않았기 때문에 발생합니다. 문자열 스캐너가 따옴표 붙은 문자열을 무시하도록하려면'cppStyleComment.ignore (quotedString) .scanString ('printf ("// 주석이 아닙니다.);'). next()'가 제대로 올릴 것입니다. 이 형식은 따옴표 붙은 문자열 안의 주석이 중요하지 않다는 추가 지정을 제공하기 때문에 StopIteration입니다. (물론 cStyleComment는 여기에 일치하지 않습니다. cStyleComments는'/*...*/'주석과 만 일치합니다.) – PaulMcG

+0

scanString은 표현식 일치를 찾기 위해 문자 단위로 이동합니다. 경우에 따라 cppStyleComment (' /*...*/'및'// ... '주석). scanString은 각각 0, 1, 2 등의 위치에서 시작합니다. 마침내 첫 번째 '' '문자를 지나쳐 첫 번째'/ '문자에 도달하면 유효한 주석을 찾습니다 * 따옴표로 묶인 문자열을 특별히 처리하는 주석 표현식의 정의에는 아무 것도 없습니다 .OP의 테스트 케이스는 따옴표 안에 주석을 포함하지 않으므로이 추가 된 필터로 솔루션을 혼란스럽게 만들지 않았습니다. – PaulMcG

관련 문제