我正在撰寫一個實用程式腳本來修復 Verilog 代碼,使用sed. 我想要做的是轉換代碼如下
輸入檔案
my_instance_name
(
.port1 (port1 )
.port2 (port2 ) // comment for port line 2
.port3 (port3 )
.port4 (port4 ) // comment for port line 4
);
我想要的是
my_instance_name
(
.port1 (port1 ),
.port2 (port2 ), // comment for port line 2
.port3 (port3 ),
.port4 (port4 ) // comment for port line 4
);
要點是
- 在每個“埠”行的右括號之后附加逗號
- 不要為最后一個“埠”附加逗號
- 如果存在則保留注釋(注釋以雙斜杠開頭,如 C)
- 空格(換行符除外)并不重要。它僅用于人類可讀性。
- 最后一個埠行之后可以有多個換行符
如果sed腳本變得太復雜,也可以只在點之前添加逗號,除了第一個埠行。即,下面的代碼是可以的,雖然它不是很漂亮。
my_instance_name
(
.port1 (port1 )
,.port2 (port2 ) // comment for port line 2
,.port3 (port3 )
,.port4 (port4 ) // comment for port line 4
);
我只能通過以下兩行管理將逗號附加到所有“埠”行
sed -i /^\s*my_instance_name.*/,/);/{s/^\(\s*\..*)\)\(\s*\/\/.*\)/\1,\2/} my_verilog.txt
sed -i /^\s*my_instance_name.*/,/);/{s/^\(\s*\..*)\)\s*\$/\1,/} my_verilog.txt
它檢測從“my_instance_name”到“);”的代碼范圍。第一行在右括號和注釋之間插入逗號。第二行是沒有注釋的埠行。
但我不知道如何排除最后一行。
uj5u.com熱心網友回復:
您可以使用此gnu-awk解決方案使用自定義RS拆分頁眉和頁腳上顯示的塊:
awk -i inplace -v RS='my_instance_name\\s*\\(\\s*' '
NF {
$0 = gensub(/(\n\s*)([^)])/, "\\1,\\2", "g")
}
{ORS=RT} 1' file
cat file
my_instance_name
(
.port1 (port1 )
,.port2 (port2 ) // comment for port line 2
,.port3 (port3 )
,.port4 (port4 ) // comment for port line 4
);
請注意,由于使用-i inplace更改將行內保存在同一輸入檔案中。
分解:
-v RS='my_instance_name\\s*\\(\\s*'拆分輸入資料,my_instance_name后跟 0 個或多個空格,然后(再后跟 0 個或多個空格。gensub函式匹配后跟 0 個或多個空格的換行符并在組 #1 中捕獲。它匹配任何不匹配的字符)(以避免匹配);行)并在組 #2 中捕獲。作為替換,我們在這兩個值之間插入一個逗號。{ORS=RT}填充與模式ORS匹配的文本相同,RS即RT1列印所有記錄
最后使用類似的 awk 附加逗號:
awk -v RS='my_instance_name\\s*\\(\\s*' '
NF {
$0 = gensub(/\)([^\n]*\n[^)])/, "),\\1", "g")
}
{ORS=RT} 1' file
my_instance_name
(
.port1 (port1 ),
.port2 (port2 ), // comment for port line 2
.port3 (port3 ),
.port4 (port4 ) // comment for port line 4
);
uj5u.com熱心網友回復:
這在 awk 中可能會容易得多。
awk '/my_instance_name/ { p=1 }
p && /\);/ { if (prev) print prev; print; p=0; next }
p && /port/ { if (prev) { sub(/\)/, "),", prev); print prev; }
prev = $0; next } 1' my_verilog.txt
標準 awk 沒有類似 ; 的-i選項sed。這將簡單地將輸出列印到標準輸出,您可以將其重定向到臨時檔案,然后移回原始檔案的頂部。或者,如果您有 GNU Awk,它-i inplace的作業方式類似于sed's -i。
uj5u.com熱心網友回復:
使用 GNUsed
$ sed -Ezi.bak 's/\([^)]*\)/&,/g;s/(\([^)]*\)),([^\n]*\n\);)/\1\2/g' input_file
my_instance_name
(
.port1 (port1 ),
.port2 (port2 ), // comment for port line 2
.port3 (port3 ),
.port4 (port4 ) // comment for port line 4
);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/524798.html
標籤:重击awksed
