【问题标题】:Use sed/awk to delete a line if the following line does not match如果以下行不匹配,请使用 sed/awk 删除一行
【发布时间】:2014-01-08 23:14:32
【问题描述】:

我有一个数据列表如下:

Account Number: 11111
Domain        : domain.com
     Quantity: 1
     Quantity: 2
    Processor: Intel Xeon E5-1650 V2 3.5GHZ, Hexa Core
    SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays

Account Number: 54321
Domain        : domain0.com
     Quantity: 1
    Processor: Intel Xeon E3-1240 V1 3.3Ghz, Quad Core
    SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays
     Quantity: 1

Account Number: 12345
Domain        : domain1.com
     Quantity: 1

我想使用 sed/awk 删除下一行中没有跟“处理器:”的所有“数量:X”条目。如果以下行不包含“数量:X”和“处理器:”,我还想删除“帐号:XXXXX”和“域:”行。这反过来会将上述数据更改为:

Account Number: 11111
Domain        : domain.com
     Quantity: 2
    Processor: Intel Xeon E5-1650 V2 3.5GHZ, Hexa Core
    SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays

Account Number: 54321
Domain        : domain0.com
     Quantity: 1
    Processor: Intel Xeon E3-1240 V1 3.3Ghz, Quad Core
    SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays

谁能提供一种方法来使用 sed 或 awk 或两者的组合来完成此任务?

【问题讨论】:

  • 你永远不需要 sed 和 awk 的组合,因为 sed 可以做任何事情,awk 可以做。此外,您永远不应该将 sed 用于不是 100% 受限于单个文本行的作业,因为这将涉及 sed 语言结构,这些结构在 1970 年中期 awk 被发明时已经过时,因此结果总是更难阅读,而且很多不如 awk 脚本健壮。

标签: regex bash sed awk


【解决方案1】:
$ cat tst.awk
BEGIN{ RS=""; FS="\n" }
/Quantity:/ && /Processor:/ {
    for (i=1; i<=NF; i++) {
        if ( ! (($i ~ /Quantity:/) && ($(i+1) !~ /Processor:/)) ) {
            print $i
        }
    }
    print ""
}
$ 
$ awk -f tst.awk file
Account Number: 11111
Domain        : domain.com
     Quantity: 2
    Processor: Intel Xeon E5-1650 V2 3.5GHZ, Hexa Core
    SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays

Account Number: 54321
Domain        : domain0.com
     Quantity: 1
    Processor: Intel Xeon E3-1240 V1 3.3Ghz, Quad Core
    SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays

【讨论】:

    【解决方案2】:

    编辑:Erf... 应该在回答之前阅读问题。
    希望这个应该可以工作

    BEGIN { 
            OFS=RS
            FS="\n"
            RS= ""
        }
    
        {
            selected = 0
            drop = 0
            for (i = 1; i <= NF ; i++)
            {
                if ($i ~ "Quantity:")
                {
                    if ($(i+1) ~ "Processor:") selected = 1
                    else  drop++
                }
                $i = $(i+drop)
            }
            if (selected) print
        }
    

    命令

    gawk -f processor.awk processor.txt
    

    输出

    Account Number: 11111
    Domain        : domain.com
         Quantity: 2
        Processor: Intel Xeon E5-1650 V2 3.5GHZ, Hexa Core
        SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays
    
    Account Number: 54321
    Domain        : domain0.com
         Quantity: 1
        Processor: Intel Xeon E3-1240 V1 3.3Ghz, Quad Core
        SERVERCHASSIS: Standard - Single PSU - No Hot Swap Bays
    

    【讨论】:

    • 你应该试试。我不认为它在 OP 所寻找的范围内。
    • @Ed 是的,应该在回答之前阅读问题直到最后。这种解决方案避免了重复关键字,尽管最终差别不大。
    最近更新 更多