追加到线是preceded其次为空行 [英] Append to line that is preceded AND followed by empty line

查看:110
本文介绍了追加到线是preceded其次为空行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要追加一个星号线,但只有当上述线路为preceded的的后跟空行(仅供参考,上述空行不会对他们有任何空格)

I need to append an asterisk to a line, but only if said line is preceded and followed by empty lines (FYI, said empty lines will NOT have any white space in them).

假设我有以下文件:

foo

foo
foo

foo

foo

我所要的输出是这样的:

I want the output to look like this:

foo

foo
foo

foo*

foo

我试图修改以下 AWK 命令(找到<一href=\"http://stackoverflow.com/questions/21517723/sed-replace-pattern-only-if-followed-by-empty-line\">here):

awk 'NR==1 {l=$0; next}
       /^$/ {gsub(/test/,"xxx", l)}
       {print l; l=$0}
       END {print l}' file

适合我的用途,但在节得到了所有捆绑起来。

to suit my uses, but got all tied up in knots.

桑达或Perl的解决方案,当然,也欢迎!

Sed or Perl solutions are, of course, welcome also!

更新:

原来,我问的问题是不太正确的。我真正需要的是code,将文本追加到非空行不以空格开始,并紧随其后,两行下,由非空行也不会与空白开始。

It turned out that the question I asked was not quite correct. What I really needed was code that would append text to non-empty lines that do not start with whitespace AND are followed, two lines down, by non-empty lines that also do not start with whitespace.

有关这个修订问题,假设我有以下文件:

For this revised problem, suppose I have the following file:

foo

third line foo

fifth line foo
 this line starts with a space foo
 this line starts with a space foo

ninth line foo

eleventh line foo

 this line starts with a space foo

last line foo

我所要的输出是这样的:

I want the output to look like this:

foobar

third line foobar

fifth line foo
 this line starts with a space foo
 this line starts with a space foo

ninth line foobar

eleventh line foo

 this line starts with a space foo

last line foo

有关的的,这个sed的一个班轮的伎俩:

For that, this sed one-liner does the trick:

sed '1N;N;/^[^[:space:]]/s/^\([^[:space:]].*\o\)\(\n\n[^[:space:]].*\)$/\1bar\2/;P;D' infile

由于以下本杰明W.的明确和翔实的答案,我能凑齐这一行!

Thanks to Benjamin W.'s clear and informative answer below, I was able to cobble this one-liner together!

推荐答案

一个sed的解决方案:

A sed solution:

$ sed '1N;N;s/^\(\n.*\)\(\n\)$/\1*\2/;P;D' infile
foo

foo
foo

foo*

foo

N;磷;ð是通过附加的下一个模式空间,然后打印和删除先来看看在同一时间两行的惯用方式行。

N;P;D is the idiomatic way to look at two lines at the same time by appending the next one to the pattern space, then printing and deleting the first line.

1N; N,P; d 扩展了总是在模式空间,这就是我们要在这里

1N;N;P;D extends that to always having three lines in the pattern space, which is what we want here.

的替代,如果第一个和最后一行是空的( ^ \\ n \\ N $ ),并匹配附加有一个 * 来的空行之间的界限。

The substitution matches if the first and last line are empty (^\n and \n$) and appends one * to the line between the empty lines.

注意,这个匹配,并附加 * 也为三个空行的第二行,你想要什么这可能不是。为了确保这种情况不会发生,第一个捕获组必须至少有一个非空白字符:

Notice that this matches and appends a * also for the second line of three empty lines, which might not be what you want. To make sure this doesn't happen, the first capture group has to have at least one non-whitespace character:

sed '1N;N;s/^\(\n[^[:space:]].*\)\(\n\)$/\1*\2/;P;D' infile


从评论的问题

我们能的追加 * 如果线两条以上 ABC 开始?


Question from comment

Can we not append the * if the line two above begins with abc?

例输入文件:

foo

foo
abc

foo

foo

foo

foo

有三种空行之间,但第一个不应该得到的 * 追加因为线路上述两个与 ABC 启动。这是可以做到如下:

There are three foo between empty lines, but the first one should not get the * appended because the line two above starts with abc. This can be done as follows:

$ sed '1{N;N};N;/^abc/!s/^\(.*\n\n[^[:space:]].*\)\(\n\)$/\1*\2/;P;D' infile
foo

foo
abc

foo

foo*

foo*

foo

本保持的在模式空间中时四驱的线,不仅使替换​​如果模式空间不与启动ABC

This keeps four lines at a time in the pattern space and only makes the substitution if the pattern space does not start with abc:

1 {      # On the first line
    N    # Append next line to pattern space
    N    # ... again, so there are three lines in pattern space
}
N        # Append fourth line
/^abc/!  # If the pattern space does not start with abc...
    s/^\(.*\n\n[^[:space:]].*\)\(\n\)$/\1*\2/   # Append '*' to 3rd line in pattern space
P        # Print first line of pattern space
D        # Delete first line of pattern space, start next cycle

二备注:


  1. BSD的sed需要一个额外的分号: 1 {N; N;} 而不是 1 {N; N}

  2. 如果该文件的第一行和第三行是空的,第二行则的的获得一个星号追加,因为我们才开始有四行模式空间检查一次。

  1. BSD sed requires an extra semicolon: 1{N;N;} instead of 1{N;N}.
  2. If the first and third line of the file are empty, the second line does not get an asterisk appended because we only start checking once there are four lines in the pattern space. This could be solved by adding an extra substitution into the 1{} block:

1{N;N;s/^\(\n[^[:space:]].*\)\(\n\)$/\1*\2/}

(记住额外的; 为BSD SED),而是试图覆盖所有的边缘情况使得sed的就更少了可读性,尤其是在单行:

(remember the extra ; for BSD sed), but trying to cover all edge cases makes sed even less readable, especially in one-liners:

sed '1{N;N;s/^\(\n[^[:space:]].*\)\(\n\)$/\1*\2/};N;/^abc/!s/^\(.*\n\n[^[:space:]].*\)\(\n\)$/\1*\2/;P;D' infile


这篇关于追加到线是preceded其次为空行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆