非常に大きなVerilogファイル(〜350 MiB)があります。その中で、特定のモジュール名にコメントしたいので、サンプルファイルを取り、正規表現を試してみました。
サンプルファイル(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_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
私は最初に正規表現と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行目;
どうすれば思い通りに動作させることができますか?
貪欲でないマッチングを使用する:
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
これはあなたが望む行をコメントアウトしているようです:
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のみ)は、一度に1行ではなく、NUL文字が見つかるまでファイルを読み取るようにsedに指示します。賢明なテキストファイルにはNUL文字が含まれないため、ファイル全体を一度に読み取る効果があります。
上記では、単一の代替コマンドを使用して、対象の行の周囲に/*
と*/
を配置しています。
ファイルをインプレースで変更するには:
sed -i.bak -z 's|HS55_LH_OPTALL_GND_Z[^;]*;|/*&*/|g' abc
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
これはラベルa
を定義します。
/;/{bb}
パターンスペースに現在;
が含まれている場合は、ラベルb
に分岐します。
N
ファイルから次の行を読み取り、パターンスペースに保存します。
ba
ラベルa
に分岐します。
:b
これはラベルb
を定義します。
s|H|/*H|; s|;|;*/|;
ここに到達すると、パターンスペースはHS55_LH_OPTALL_GND_Z
を含む行で始まり、;
を含む行で終わることを意味します。このパターンスペースでは、最初のH
の前に/*
を置き、最初の*/
の後に;
を置きます。