求TCL/SHELL脚本:匹配替换两文件中的布局坐标数据
文件匹配替换:从file2提取坐标更新file1
问题说明
我有两个大文件,格式如下:
file1 内容:
place u_RX_WR_SE1_LS { } R0 -place place u_bank_LS { } R0 -place
file2 内容:
set inst RX_WR_SE1_PD ; add -inst $inst -cell PR ; place $inst 5.76 5305.84 0 set inst RX_WR_SE2_PD ; add -inst $inst -cell PR ; place $inst 5.76 5338.864 0 set inst bank_PD ; add -inst $inst -cell PR ; place $inst 5.76 5371.888 0
需求:
- 提取file1第二字段中去掉开头
u_和结尾_LS后的内容(比如RX_WR_SE1) - 在file2中搜索该内容,匹配成功后,把file2对应行的第13、14字段(坐标值)复制到file1对应行的
{ }内
期望输出:
place u_RX_WR_SE1_LS { 5.76 5305.84 } R0 -place place u_bank_LS { 5.76 5371.888 } R0 -place
我之前试了一段Awk脚本,但没得到正确结果:
awk 'FNR==NR{gsub(/u_|_LS/,"",$2);arr[$2]="";next} { for (i in arr) { if ($0 ~ i) {print i,$13,$14}} } ' file1 file2
Shell(Awk)正确解决方案
核心思路是先把file2中的坐标数据存成键值对,再遍历file1做替换。修改后的Awk脚本如下:
awk ' # 处理file2:提取inst前缀和对应的坐标 FNR == NR { # 提取第二个字段,去掉末尾的_PD作为匹配key key = $2 sub(/_PD$/, "", key) # 第13、14字段是坐标,存入数组 coords[key] = $13 " " $14 next } # 处理file1:替换{ }里的内容 { # 提取第二个字段,去掉开头u_和结尾_LS key = $2 sub(/^u_/, "", key) sub(/_LS$/, "", key) # 找到对应坐标则替换 if (key in coords) { gsub(/\{ \}/, "{ " coords[key] " }") } print $0 } ' file2 file1
脚本说明
- 先处理file2:
- 对每行的第二个字段(如
RX_WR_SE1_PD)去掉末尾_PD,作为匹配key - 将该行第13、14字段的坐标值存入数组
coords[key]
- 对每行的第二个字段(如
- 再处理file1:
- 对每行的第二个字段(如
u_RX_WR_SE1_LS)去掉开头u_和结尾_LS,得到匹配key - 若key存在于坐标数组中,就把行内的
{ }替换为包含坐标的{ 坐标值 } - 输出修改后的行
- 对每行的第二个字段(如
TCL解决方案
如果偏好TCL语言,可使用以下脚本实现:
# 读取file2,建立inst到坐标的字典 set f2 [open "file2" r] set coord_dict [dict create] while {[gets $f2 line] != -1} { set parts [split $line] set inst [lindex $parts 2] # 去掉inst末尾的_PD set key [string range $inst 0 end-3] # TCL索引从0开始,取第12、13位元素作为坐标 set x [lindex $parts 12] set y [lindex $parts 13] dict set coord_dict $key "$x $y" } close $f2 # 读取file1,替换并输出 set f1 [open "file1" r] while {[gets $f1 line] != -1} { set parts [split $line] set inst [lindex $parts 1] # 去掉开头u_和结尾_LS set key [string range $inst 2 end-3] if {[dict exists $coord_dict $key]} { set coords [dict get $coord_dict $key] set new_line [regsub -all {\{ \}} $line "{ $coords }"] puts $new_line } else { puts $line } } close $f1
脚本说明
- 遍历file2的每一行,分割后提取inst名称,去掉
_PD作为key,将对应坐标存入字典 - 遍历file1的每一行,分割后提取第二个字段,去掉
u_和_LS得到key,查字典找到坐标后替换{ },最后输出修改后的行
内容的提问来源于stack exchange,提问作者Shreya
相关产品推荐
相关产品推荐

