【问题标题】:How to use cut and awk commands to extract text input in a tabular format?如何使用 cut 和 awk 命令以表格格式提取文本输入?
【发布时间】:2014-06-20 06:19:24
【问题描述】:

我有文件 input.txt 如下:

文件名:test1.v

BUG: bug 102 is fixed by some user
IO_CHANGE: there is no io_change for this version
FEATURE: no feature added

文件名:test2.v

BUG: bug 103 is fixed by some user 
also bug 105 is fixed
IO_CHANGE: there is no io_change for this version
FEATURE: yes feature number 3 also feature 23
and feature 34 is added

文件名:test3.v

BUG: bug 104 is fixed by some user
FEATURE: yes feature number 2
IO_CHANGE: 

我的问题:- 有时对 BUG/FEATURE/IO_CHANGE 有很长的描述,其中有 2 行,或者有时 IO_CHANGE 中没有任何内容,所以它是空白的。输出文件应该包含所有错误的列表,然后是功能和 io_changes。这 3 种类型可以在输入文件中以任意顺序排列,我需要从文件中找到所有错误/功能/io_changes 并逐列列出。

【问题讨论】:

    标签: linux shell awk cat


    【解决方案1】:

    这个怎么样。我们将每个文件的值存储在一个数组中。在这里,我连接出现在多行上的条目。

    awk 'function dump() {if (vc>0) 
            print fn, vals["BUG"], vals["FEATURE"], vals["IO_CHANGE"]
        } 
        BEGIN {FS=":";OFS="\t";vc=0} 
        FNR==1 {dump();val=""; delete vals; fn=FILENAME; vc=0} 
        NF>1 {val=$1; vals[val]=vals[val] $2; vc++} 
        NF==1 {vals[val] = vals[val] " " $1} 
        END{dump()}' test*v
    
    1. dump() 函数用于将记录写入文件。
    2. BEGIN 将“:”分配给字段分隔符(因此在此解决方案中,不允许将“:”作为字段中的文本)。输出由制表符分隔。
    3. 然后在每个文件的开头 (FNR=1) 我们转储记录(如果有的话),然后我们重置或收集。
    4. 然后,如果一行有一个“:”(这将导致 NF>1),我们会跟踪我们正在设置的值并将其存储在数组中。如果没有“:”(使 NF==1),那么我们只需添加到我们要添加的最后一个值。
    5. 最后,在最后一个文件的末尾,我们最后一次转储内容。

    【讨论】:

    • 由于您正在打印$2 并将: 用作FS,因此不会打印没有: 的行
    • 谢谢@Jidder。我在NF==1 条件中有一个类型。它现在可以正确折叠多行。
    【解决方案2】:

    如果找到短语,则设置一个变量,如果找到其他短语之一,则取消设置它,然后根据文件名将行保存到数组。
    删除之前的所有内容:在每一行
    然后在列中打印该行

    #!/bin/bash
    
    awk     'BEGIN{printf("%-8s%-60s%-60s%-20s\n\n","FILE","|BUG","|IO","|FEATURE")}
        /BUG/{a=1}/IO_CHANGE:/ || /FEATURE/{a=0} {if (a){Bug[FILENAME]=Bug[FILENAME]""$0" "}}
        /IO_CHANGE:/{b=1}/BUG/ || /FEATURE/{b=0} {if (b){IO[FILENAME]=IO[FILENAME]$0" "}}
        /FEATURE/{c=1}/IO_CHANGE:/ || /BUG/{c=0} {if (c){Feat[FILENAME]=Feat[FILENAME]$0" "}}
         END{
                 for (k in Bug){
                        Bug[k] = substr(Bug[k],index(Bug[k],":"))
                        IO[k] = substr(IO[k],index(IO[k],":"))
                        Feat[k] = substr(Feat[k],index(Feat[k],":"))
                        printf("%-8s%-60s%-60s%-20s\n\n","|"k,"|"Bug[k],"|"IO[k],"|"Feat[k])}}
    '  test*v
    

    不幸的是,这不会为每个文件打印多行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-28
      • 2019-08-08
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多