【问题标题】:Extract specific cell from netlist从网表中提取特定单元
【发布时间】:2017-09-04 13:01:06
【问题描述】:

例如网表是:

INV i0 (.I(a0),
    .O(b0));

BUF i1 (.I(a1),
    .O(b1));

我想从网表中提取 BUF 单元并写入另一个文件。 如您所知,网表的单元格内总是有换行符,定位我要提取的单元格的正则表达式格式是什么?

我试过grep ^BUF.*$,但它只会返回BUF i1 (.I(a1),,因为有一个换行符,我无法提取整个BUF单元格。

【问题讨论】:

    标签: regex awk sed grep verilog


    【解决方案1】:

    使用 sed:

    sed -n '/^BUF/{N;p}' file
    

    当找到^BUF 时,该行与下一行(N) 和输出(p) 合并。

    【讨论】:

      【解决方案2】:

      grep解决方案:

      $ grep -Poz 'BUF[^;]+;' input.txt
      BUF i1 (.I(a1),
      .O(b1));
      BUF i1 (.I(a1),
      .O(b1));
      

      awk解决方案:

      $ cat vlg.awk
      BEGIN { RS="" }
      /BUF/
      

      输入:

      $ cat input.txt
      INV i0 (.I(a0),
      .O(b0));
      
      BUF i1 (.I(a1),
      .O(b1));
      
      INV i0 (.I(a0),
      .O(b0));
      
      BUF i1 (.I(a1),
      .O(b1));
      

      输出:

      $ awk -f vlg.awk input.txt
      BUF i1 (.I(a1),
      .O(b1));
      BUF i1 (.I(a1),
      .O(b1));
      

      或者只是命令行:$ awk 'BEGIN {RS=""} /BUF/' input.txt

      Note: 在awk方案中,这里要注意RS=""RS="\n\n+"的区别。第一个选项忽略输入数据中的前导换行符,并且 - 如果文件在最后一条记录之后没有额外的空白行结束 - 最后的换行符将从记录中删除。使用第二个选项,这个特殊处理没有完成。在gawk docs 中阅读有关此内容的信息。 Ed Morton 使用的 cmets。`

      【讨论】:

      • 您应该提到,由于多字符 RS,awk 解决方案只能在 GNU awk 中工作。让他们在任何 awk 中工作,将 RS="\n\n" 更改为 RS=""。此外,在 awk 中,/BUF/ { print $0 } 通常只写为/BUF/,因为{print $0} 是在真实条件下的默认操作。如果您可以输出多条记录,您还应该设置ORS="\n\n" 以匹配输入的空行分隔格式。
      • 您应该提到RS="" 导致输入数据文件中的前导换行符被忽略,如果文件在最后一条记录之后没有多余的空行结束,则从记录中删除最后的换行符。尔格:这是+1。我同意,明确的印刷品应该去。 ORS="\n\n" 添加是一个假设。
      • 如果文件开头有任何完全空的行,那么是的,它们会被忽略,但是a)为什么它们会在那里,b)如果它们存在,那么为什么不应该忽略它们c) 段落模式的行为已经有据可查,并且与使用默认 FS 时忽略记录中的前导空格的方式一致 - 每次使用时都不需要描述。没有空行的文件不会导致最后的换行符被删除。是的,必须假设 OP 是否需要输出记录之间的换行符,例如输入中的换行符。
      • 啊,我明白了,现在我明白你为什么说if a file ends without extra blank lines after the last record, the final newline is removed from the record - 这是强调使用RS="\n\n+" 可能出现的意外问题,而不是在谈论使用-v RS=""
      【解决方案3】:

      grep oneliner

      grep "BUF " -A1 input >> output
      

      对于每个BUF 匹配,打印匹配的行和它之后的一行。

      输出文件:

      BUF i1 (.I(a1),
          .O(b1));
      

      【讨论】:

        【解决方案4】:

        这将与任何 UNIX 系统上的任何 awk 一起稳健地工作:

        awk -v RS= '$1=="BUF"' file
        

        如果您可以在输入中有多个“BUF”块,那么您可能希望输出中的空白行与输入中的空白行相同,因此您可以使用:

        awk -v RS= -v ORS='\n\n' '$1=="BUF"' file
        

        到目前为止,上述答案与任何其他答案之间的主要区别在于,由于它对每条记录中的第一个非空白字符串进行精确的字符串比较,因此无论行上 BUF 前面的空格如何,它都可以工作,甚至可以工作如果类似的文本(例如 BUFFER)出现在其他行上,并且即使 BUF 出现在文件其他部分的错误位置(例如在 cmets 中?)也会起作用。

        以这个输入文件为例:

        $ cat file
        INV i0 (.I(a0), # not BUF here
            .O(b0));
        
          BUF i1 (.I(a1),
            .O(b1));
        
        BUFFER i1 (.I(a1),
            .O(b1));
        

        以下是目前所有提议的解决方案的行为方式:

        $ awk -v RS= '$1=="BUF"' file
          BUF i1 (.I(a1),
            .O(b1));
        $
        
        $ sed -n '/^BUF/{N;p}' file
        BUFFER i1 (.I(a1),
            .O(b1));
        $
        
        $ awk 'BEGIN {RS=""} /BUF/' file
        INV i0 (.I(a0), # not BUF here
            .O(b0));
          BUF i1 (.I(a1),
            .O(b1));
        BUFFER i1 (.I(a1),
            .O(b1));
        $
        
        $ grep -Poz 'BUF[^;]+;' file
        BUF here
            .O(b0));BUF i1 (.I(a1),
            .O(b1));BUFFER i1 (.I(a1),
            .O(b1));$
        $
        
        $ grep "BUF " -A1 file
        INV i0 (.I(a0), # not BUF here
            .O(b0));
        --
          BUF i1 (.I(a1),
            .O(b1));
        $
        

        【讨论】:

          猜你喜欢
          • 2020-06-24
          • 2022-11-18
          • 2021-11-03
          • 2017-03-18
          • 2016-01-11
          • 2016-01-03
          • 1970-01-01
          • 1970-01-01
          • 2021-09-07
          相关资源
          最近更新 更多