逐行条件编辑

时间:2021-07-25 14:52:06

标签: perl one-liner

我的问题更像是一个优化问题,而不是一个“操作方法”。
我有一个 lef 文件,格式为:

RECT 429.336 273.821 426.246 274.721 ;

我想使用单线将某个点上方的所有矩形向左移动 4 um:

perl -lane '$F[2] > 1200 ? print $F[0]," ", ($F[1] - 4)," ", $F[2]," ", ($F[3] -4)," ", $F[4], " ;" : print $_' trial.lef

事实是,这丑陋
有没有更好的编辑文件的方法?

我不挑剔,只要其他语言(awk、sed 等)比我写的更好,我很乐意得到答案。

附加输入:

      LAYER M12 ;
        RECT 0 411.214 1 412.214 ; <-- shouldn't change, because 411.214 < 1200
    END
  END kuku_pin
  PIN gaga_pin
    DIRECTION OUTPUT ;
    USE SIGNAL ;
    PORT
      LAYER M11 ;
        RECT 43.1045 1203.138 43.1805 1207.29 ; <-- should change to "RECT 39.1045 1203.138 39.1805 1207.29"
    END

1 个答案:

答案 0 :(得分:3)

确实没有太大的改进空间,但是您可以将 -n 替换为 -p 以跳过额外的 print。此外,您可以编辑数组元素并使用 join 以获得更漂亮的代码:

perl -lape'if ($F[2] > 1200) { $F[1] -= 4; $F[3] -= 4; $_ = join " ", @F }'
  • -a 自动拆分模式,在空间上拆分行 $_ 并将值放入预定义的 @F 数组中。此开关与 -n-p 一起使用。
  • -p 围绕 <> 操作符输入、文件或标准输入循环
  • -= 以 RHS 为单位减少 LHS
  • join 完成数学运算后将线重新连接在一起
  • 在这种情况下可以跳过
  • -l,因为我们从不触及行尾,但如果我们决定编辑最后一个字段,保留它会使代码更加灵活。

不满足条件时,原行原样打印。否则,它会替换为 @F 中的连接值。

如果您决定在 RECT 之前保留前导空格,您可以用

包围 if 语句
if (($pre) = /^(\s*RECT)/)

要存储行的开头,使单行:

perl -lape'if (($pre) = /^(\s*RECT)/) { if ($F[2] > 1200) { $F[1] -= 4; $F[3] -= 4; $F[0] = $pre; $_ = join " ", @F }}'