我有一个非常大的 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 行到最后一行的第一个匹配;
。然后,第七行到最后;
(分号)。然后,从第 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
这定义了一个标签
a
。/;/{bb}
如果模式空间当前包含
;
,则分支到 labelb
。N
从文件中读取下一行并将其存储在模式空间中。
ba
分支到标签
a
。:b
这定义了标签
b
。s|H|/*H|; s|;|;*/|;
如果我们到达这里,这意味着模式空间以包含 的行开始
HS55_LH_OPTALL_GND_Z
,并以包含 的行结束;
。对于这个模式空间,我们将 a 放在/*
第一个前面H
,将 a*/
放在第一个后面;
。