Linux数据过滤命令

Linux数据过滤命令

我有一个文件,其中包含多行数据

editPin -pin phy_inst/i_dfi_row_cmd_p1_d[0] ctrl_soft_phy_inst/hbm_ch_tile_4_hbm_tile_inst/o_phy_row_cmd_p1[0] -assign {1443.0305 184.62} -layer M10 -pinWidth 0.038 -pinDepth 0.395 -fixOverlap false -fixedPin -snap MGRID
editPin -pin phy_inst/i_dfi_row_cmd_p1_d[1] ctrl_soft_phy_inst/hbm_ch_tile_4_hbm_tile_inst/o_phy_row_cmd_p1[0] -assign {1444.0305 185.62} -layer M10 -pinWidth 0.038 -pinDepth 0.395 -fixOverlap false -fixedPin -snap MGRID

我想执行一些操作,我想像这样设置我的线

eval editPin -pin i_dfi_row_cmd_p1_d[0]  -assign { 0 [ expr 1443.0305 184.62]} -layer M10 -pinWidth 0.038 -pinDepth 0.395 -fixOverlap false -fixedPin -snap MGRID
eval editPin -pin i_dfi_row_cmd_p1_d[1]  -assign { 0 [ expr 1444.0305 185.62]} -layer M10 -pinWidth 0.038 -pinDepth 0.395 -fixOverlap false -fixedPin -snap MGRID

我单独使用了这些命令,尝试了它们,它按照我想要的结构工作。

awk '{$4=""; print $0}' all_pin 
awk '{print "eval " $0}' all_pin 
sed -e /^editPin/'{ s#phy_inst/## ; s/{/{ 0 [ expr / ; s/}/]}/ ; }' all_pin

但是当我一起使用这些命令时,它没有给出我想要的结果

cat all_pin | awk '{$4=""; print $0}' all_pin | awk '{print "eval " $0}' all_pin | sed -e /^editPin/'{ s#phy_inst/## ; s/{/{ 0 [ expr / ; s/}/]}/ ; }' all_pin

我可以知道这个问题的解决方案吗

我想对这个块执行加法操作

-assign { 0 [ expr 1443.0305 362.764+X]}

X是一个常数值,我想添加X362.764 使用命令。我试过了,但得到了错误的答案

awk '{print $10+100}' all_pin

请帮助我摆脱困境

答案1

在组合命令中,您仍然为管道中的每个项目指定一个源文件:

cat all_pin | awk '{$4=""; print $0}' all_pin | awk '{print "eval " $0}' all_pin | sed -e /^editPin/'{ s#phy_inst/## ; s/{/{ 0 [ expr / ; s/}/]}/ ; }' all_pin
#   ^source                           ^again                             ^and again                                                                    ^and still again

相反,您应该让每个命令读取其前一个命令。在这里,我组合了这两个awk命令并丢弃了不必要的cat

awk '{ $4=""; print "eval " $0}' all_pin |
    sed -e '/^editPin/ { s#phy_inst/## ; s/{/{ 0 [ expr / ; s/}/]}/ ; }'

取决于我的答案评论问题第二部分可能同样简单,我将相应地更新我的答案

答案2

为什么不使用 tcl 进行加法呢?下面是一个示例,仅将表达式更改为具有嵌套表达式,以便您可以调整 tcl 中的第二个值。

$ echo editPin -pin phy_inst/blah args  -assign {1443.0305 184.62} -options | \
    sed  '/editPin.*phy_inst/s/assign {\([0-9.]*\) \([0-9.]*\)}/assign { 0 [ expr \1 [ expr \2 + 123.3]]}/'
# returns editPin -pin phy_inst/blah args -assign { 0 [ expr 1443.0305 [ expr 184.62 + 123.3]]} -options

这样 sed 只是一个简单的字符串替换,并且您不会尝试在 shell/awk/bc/etc 中进行任何浮点数学运算。

答案3

我想出了这个 awk

 {  for(i=1; i<=NF ; i++ ) {
        if ( $i ~ /^phy_inst/ ) {
                $i=substr($i,10) ;
                $(i+1)="" ; }
        if ( $i == "-assign" ) {
                $(i+1)="{ 0 [ expr " $(i+1) ;
                $(i+2)=$(i+2) "+" X " ]}" ;
                }
 }
        $1 = "eval " $1 ;
         print ;
 }

被调用(用适当的值替换 foo_bar)

awk -v X=foo_bar -f SE.awk all_pin

屈服

eval editPin -pin i_dfi_row_cmd_p1_d[0]  -assign { 0 [ expr {1443.0305 184.62}+foo_bar ]} -layer M10 -pinWidth 0.038 -pinDepth 0.395 -fixOverlap false -fixedPin -snap MGRID
eval editPin -pin i_dfi_row_cmd_p1_d[1]  -assign { 0 [ expr {1444.0305 185.62}+foo_bar ]} -layer M10 -pinWidth 0.038 -pinDepth 0.395 -fixOverlap false -fixedPin -snap MGRID

其中 awk 基本上逐行解析,

  • 解析是通过循环所有“字段”来完成的,awk使用NF变量(字段数,请参阅man awk
  • 在第一个字段中添加 eval
  • 剥离phy_inst/字符串,删除以下字段(隐式指定)
  • 编辑-assign字段后的值
  • 插入变量的值X(必须在命令行上调用)(对于变量名来说是一个糟糕的选择)

未经测试

    if ( $i == "-assign" ) {
            $(i+1)="{ 0 [ expr " ($(i+1)+X) ;
            $(i+2)=($(i+2) + X) " ]}" ;
            }

只需将 X 值添加到适当的字段即可。

相关内容