在 Solaris 中删除 2 个字符串之间的行

在 Solaris 中删除 2 个字符串之间的行

我想使用基本的 awk 或 sed 删除两个模式之间的所有行。

foo.txt:

----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
---------------------------------------------------  Cap in MB
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

output.txt:

----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

我使用的是Solaris 5.10,仅使用基本的awk 和sed。 2 个图案之间的线数可能会有所不同。请注意,必须替换第二个字符串,而不是第一个字符串。请注意,两种模式之间的区别在于破折号的数量。你看到的foo.txt正是我的真实文件。

答案1

 $ awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point

怎么运行的

该脚本有一个变量f。当f为 true (1) 时,我们处于要删除的行范围内。当它为假(0)时,我们处于应该打印的范围内。

默认情况下,f程序启动时为 false。

  • !f{print}

    f当为 false时打印任意行。

  • /----------------------/{f=!f;if (!f)print "Deleted up to this point"}

    如果我们到达由虚线标记的分隔线,则反转 的值f。如果 f 现在为 false,则打印“已删除”消息。

更新

Solaris 上的默认 awk 似乎有问题。尝试:

nawk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

或者,

/usr/xpg4/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

或者,

/usr/xpg6/bin/awk '!f{print} /----------------------/{f=!f;if (!f)print "Deleted up to this point"}' foo.txt

回答修改后的问题

$ awk ' /^---------------------------------------------------  Cap in MB/{print "Deleted up to this point"; f=0; z=""; next;} /^----------------------------------------------------------------------  Cap in MB/{f=1; if(z)print substr(z,2); z=""; print;next;}  f{z=z"\n"$0;next;} END{print substr(z,2);}' foo.txt
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
Deleted up to this point
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5
----------------------------------------------------------------------  Cap in MB
line 2
line 3
line 4
line 5

答案2

这是 awk 的一个简单解决方案:关闭长虚线后的打印,打开短虚线后的打印。

awk '
    !do_not_print {print}
    $0 == "----------------------------------------------------------------------  Cap in MB" {do_not_print = 1}
    $0 == "---------------------------------------------------  Cap in MB" {do_not_print = 0}
' <foo.txt >output.txt

答案3

我的看法是。与 John1024 类似,但由于他的内容在一行中,因此无法阅读。
在 Solaris 8 机器上进行测试。

/usr/xpg4/bin/awk \
    -v section_start='^----------------------------------------------------------------------  Cap in MB' \
    -v delete_marker='^---------------------------------------------------  Cap in MB' \
'
    $0 ~ section_start {
        for (i=1; i<=n; i++) 
            print line[i]
        n=0
        delete line
        print
        next    
    }
    {line[++n] = $0}
    $0 ~ delete_marker {
        n=1
        delete line
        line[1] = "Deleted up to this point"
    }
    END {for (i=1; i<=n; i++) print line[i]}
' foo.txt

相关内容