정규식 및 sed를 사용하여 특정 줄에 주석 달기

정규식 및 sed를 사용하여 특정 줄에 주석 달기

매우 큰 Verilog 파일(~350MiB)이 있습니다. 거기에 특정 모듈 이름을 언급하고 싶습니다. 그래서 샘플 파일을 가져와서 정규식을 사용해 보았습니다.

샘플 파일(abc):-

module util_minor_rev_id(minor_rev);
 output [3:0] minor_rev;
 wire [3:0] minor_rev;
 wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
 HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
      (minor_rev[0]));
 HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
      (minor_rev[1]));
xyz
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
      (minor_rev[2]));
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
      (minor_rev[3]));
endmodule

HS55_LH_OPTALL_GND_ZUntil 이 포함된 행을 주석 처리하고 싶으 ;므로 출력은 다음과 같아야 합니다.

module util_minor_rev_id(minor_rev);
 output [3:0] minor_rev;
 wire [3:0] minor_rev;
 wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
     (minor_rev[0]));*/
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
     (minor_rev[1]));*/
xyz
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
      (minor_rev[2]));*/
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
      (minor_rev[3]));*/
endmodule

먼저 정규식과 grep을 사용하여 패턴의 유효성을 검사해 보았습니다. 여러 줄 모드를 사용하여 검색하는 데 문제가 있습니다. 그래서 구글링을 해보니 pcregrep내 친구였다.

pcregrep -Mno '^\s\*HS55_LH_OPTALL_GND_Z.*(\n|.)+;$' abc

그러나 출력은 다음과 같습니다:-

5:  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
       (minor_rev[0]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
       (minor_rev[1]));
xyz
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
       (minor_rev[2]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));
7:  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
       (minor_rev[1]));
xyz
HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
       (minor_rev[2]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));
10:HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
       (minor_rev[2]));
  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));
12:  HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
       (minor_rev[3]));

5번째 줄부터 마지막 ​​줄까지가 첫 경기인 것 같아요 ;. 그런 다음 7행 끝 ;(세미콜론)까지 입력합니다. 그런 다음 10행부터 끝까지 이동합니다 ;. 그럼 12번째 줄부터 끝까지;

내가 원하는 대로 작동하게 하려면 어떻게 해야 합니까?

답변1

탐욕스럽지 않은 일치를 사용하십시오.

pcregrep -Mno '^\s*HS55_LH_OPTALL_GND_Z.*(\n|.)*?;$' file

산출:

5:      HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
           (minor_rev[0]));
7:      HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
           (minor_rev[1]));
10:HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
           (minor_rev[2]));
12:      HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
           (minor_rev[3]));

Vim을 사용하여 다음 줄에 주석을 달 수도 있습니다:

:%s!^\s*\zsHS55_LH_OPTALL_GND_Z\_.\{-};$!/* & */!

결과:

module util_minor_rev_id(minor_rev);
    output [3:0] minor_rev;
    wire [3:0] minor_rev;
    wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
    /* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
        (minor_rev[0])); */
    /* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
        (minor_rev[1])); */
xyz
/* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
        (minor_rev[2])); */
    /* HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
        (minor_rev[3])); */
    endmodule

답변2

GNU sed 사용

이것은 원하는 줄을 주석 처리한 것 같습니다.

sed -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc

예를 들어:

$ sed -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc
module util_minor_rev_id(minor_rev);
      output [3:0] minor_rev;
      wire [3:0] minor_rev;
      wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
           (minor_rev[0]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
           (minor_rev[1]));*/
xyz
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
           (minor_rev[2]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
           (minor_rev[3]));*/
    endmodule

-z옵션(GNU에만 해당)은 sed에게 파일을 한 번에 한 줄씩 읽지 않고 NUL 문자가 발견될 때까지 읽도록 지시합니다. 정상적인 텍스트 파일에는 NUL 문자가 없으므로 전체 파일을 한 번에 읽는 효과가 있습니다.

위의 내용은 단일 대체 명령을 사용하여 관심 있는 선을 배치 /*하고 둘러쌉니다.*/

현재 위치에서 파일을 변경하려면:

sed -i.bak -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc

다른 sed를 사용하세요

BSD/OSX 또는 기타 sed의 경우:

sed '/HS55_LH_OPTALL_GND_Z/{:a; /;/{bb}; N; ba; :b; s|H|/*H|; s|;|;*/|;}' abc

예를 들어:

$ sed '/HS55_LH_OPTALL_GND_Z/{:a; /;/{bb}; N; ba; :b; s|H|/*H|; s|;|;*/|;}' abc
module util_minor_rev_id(minor_rev);
      output [3:0] minor_rev;
      wire [3:0] minor_rev;
      wire n_15, n_16, n_17, n_18, n_19, n_20, n_21, n_22;
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id0(.A (1'b1), .Z
           (minor_rev[0]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id1(.A (1'b1), .Z
           (minor_rev[1]));*/
xyz
/*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id2(.A (1'b1), .Z
           (minor_rev[2]));*/
      /*HS55_LH_OPTALL_GND_Z opt_plug_minor_rev_id3(.A (1'b1), .Z
           (minor_rev[3]));*/
    endmodule

현재 위치에서 파일을 변경하려면:

sed -i.bak '/HS55_LH_OPTALL_GND_Z/{:a; /;/{bb}; N; ba; :b; s|H|/*H|; s|;|;*/|;}' abc

제한 사항: 이러한 sed 명령은 파일을 구문 분석하지 않으므로 경우에 따라 잘못된 작업을 수행할 수 있습니다.

어떻게 작동하나요?

  • /HS55_LH_OPTALL_GND_Z/{...}

    그러면 포함된 행이 선택되고 HS55_LH_OPTALL_GND_Z해당 행에 대해 중괄호 안의 명령이 실행됩니다. 이러한 명령은 아래에 설명되어 있습니다.

  • :a

    이는 label 을 정의합니다 a.

  • /;/{bb}

    패턴 공간에 현재 가 포함되어 있으면 ;label 로 분기합니다 b.

  • N

    파일에서 다음 줄을 읽고 이를 패턴 공간에 저장합니다.

  • ba

    태그로 분기합니다 a.

  • :b

    이는 레이블을 정의합니다 b.

  • s|H|/*H|; s|;|;*/|;

    여기에 도달하면 패턴 공간이 포함 라인으로 시작 HS55_LH_OPTALL_GND_Z하고 포함 라인으로 끝난다는 의미입니다 ;. 이 패턴 공간의 경우 /*첫 번째 것 앞에 a를 넣고 첫 번째 것 뒤에 Ha를 넣습니다 .*/;

관련 정보