sed:删除以标记结尾的行后面的空白行

发布于 2024-12-09 16:32:02 字数 2181 浏览 0 评论 0原文

如何使用 sed 执行此操作?

    Input:                         Expected output:
    1               |              1
    2 MARKER        |              2 MARKER
                    |              3 MARKER
                    |              4
                    |              
                    |              5 MARKER
                    |              6
                    |              
    3 MARKER        |              
                    |              7 MARKER
    4               |              8
                    |              9
    5 MARKER        |                      
    6               |               
                    |              
                    |              
    7 MARKER        |                      
                    |              
    8               |               
    9               |               

首先我尝试了这个:它不起作用,因为“# t 或 b 都不起作用,因为 d 导致脚本中断。”

/MARKER$/ {
#   i -- Line with MARKER
:my_branch
#   i -- in branch
    # write current patt space to output and read next line to pattern space
    n
    # if non blank goto EO script
    /^$/! b
    # if blank line delete it
    /^$/ d
    # loop back for more blank lines.
    t my_branch
    # niether t or b work because d causes the script to break.
    b my_branch
}

然后我尝试了这个,这几乎有效:((( -- 它不会删除 3 和 4 之间的线,我认为这是因为 3 在处理 2 的过程中被消耗,因此它的标记被遗漏了。

/MARKER$/ {
#       i -- Line with MARKER
:my_branch
#   i -- in branch
    N
    s/MARKER\n/MARKER/
    t my_branch
    # I added the following but it doesn't help..
    /MARKER$/ b my_branch
}

有 4-5我尝试过其他版本,但没有一个有效。

我这样做是因为我试图回答这个问题:在 shell 命令行中将两个换行符替换为一个换行符,所以我从 http://sed.sourceforge.net/sed1line.txthttp ://www.grymoire.com/Unix/Sed.html

IOW 我知道有使用 awk、perl 等的解决方案,但我只是想学习使用 sed

谢谢。

How do I do this using sed?

    Input:                         Expected output:
    1               |              1
    2 MARKER        |              2 MARKER
                    |              3 MARKER
                    |              4
                    |              
                    |              5 MARKER
                    |              6
                    |              
    3 MARKER        |              
                    |              7 MARKER
    4               |              8
                    |              9
    5 MARKER        |                      
    6               |               
                    |              
                    |              
    7 MARKER        |                      
                    |              
    8               |               
    9               |               

First I tried this: It doesn't work coz "# niether t or b work because d causes the script to break."

/MARKER$/ {
#   i -- Line with MARKER
:my_branch
#   i -- in branch
    # write current patt space to output and read next line to pattern space
    n
    # if non blank goto EO script
    /^$/! b
    # if blank line delete it
    /^$/ d
    # loop back for more blank lines.
    t my_branch
    # niether t or b work because d causes the script to break.
    b my_branch
}

then I tried this, which almost works :((( -- it doesn't remove the line between 3 and 4, which I think is because 3 is consumed during the processing of 2 and thus it's marker is missed.

/MARKER$/ {
#       i -- Line with MARKER
:my_branch
#   i -- in branch
    N
    s/MARKER\n/MARKER/
    t my_branch
    # I added the following but it doesn't help..
    /MARKER$/ b my_branch
}

there 4-5 other versions I tried, but none worked.

I did all this because I was trying to answer this question: replace two newlines to one in shell command line, so I started learning sed from http://sed.sourceforge.net/sed1line.txt and http://www.grymoire.com/Unix/Sed.html

IOW I know there are solutions using awk, perl etc but I just wanted to learn using sed.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夕嗳→ 2024-12-16 16:32:02

见下文,我想这就是你想要的:(它在我的 Linux 机器上使用 gnu sed 运行)

kent$  cat t
1         
2 MARKER  






3 MARKER  

4         

5 MARKER  
6         


7 MARKER  

8         
9         

kent$  sed -r ':a;N;s/(.*MARKER)\s+(\n.*)/\1\2/;ba;' t
1         
2 MARKER
3 MARKER
4         

5 MARKER
6         


7 MARKER
8         
9    

see below, I think it is what you want: (it ran on my linux box with gnu sed)

kent$  cat t
1         
2 MARKER  






3 MARKER  

4         

5 MARKER  
6         


7 MARKER  

8         
9         

kent$  sed -r ':a;N;s/(.*MARKER)\s+(\n.*)/\1\2/;ba;' t
1         
2 MARKER
3 MARKER
4         

5 MARKER
6         


7 MARKER
8         
9    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文