如何在匹配模式的每一行的开始和结尾添加新的行?

时间:2022-01-28 06:33:52

How can sed be used to add a \n to the beginning and to the end of every line matching the pattern %%###? This is how far I got:

如何使用sed来将一个\n添加到每一行的开头和结尾,以匹配模式%%###?这就是我所得到的:

If foo.txt contains

如果foo。txt包含

foobar
%%## Foo
%%### Bar
foobar

then sed 's/^%%###/\n&\n/g' foo.txt gives

然后sed ' s / ^ % % # # # / \ n \ n / g的foo。三种了

foobar
%%## Foo

%%###
 Bar
foobar

instead of

而不是

foobar
%%## Foo

%%### Bar

foobar

Note: This seems related to this post

注意:这似乎与这篇文章有关

Update: I'm actually looking for case where lines starting with the pattern are considered only.

更新:我实际上在寻找只考虑以模式开头的行的情况。

4 个解决方案

#1


1  

With GNU sed:

GNU sed:

sed 's/.*%%###.*/\n&\n/' file

Output:

输出:

foobar
%%## Foo

%%### Bar

foobar

&: Refer to that portion of the pattern space which matched

&:指模式空间中匹配的部分

If you want to edit your file "in place" use sed's option -i.

如果你想编辑你的文件“到位”使用sed的选项-i。

#2


1  

It is cumbersome to directly add newlines via sed. But here is one option if you have perl available:

通过sed直接添加新行是很麻烦的。但如果您有perl可用,这里有一个选项:

$ foo.txt | perl -pe 's/(.*%%###.*)/\n$1\n/'

Here we capture every matching line, which is defined as any line containing the pattern %%### anywhere, and then we replace with that line surrounded by leading and trailing newlines.

在这里,我们捕获每一个匹配的行,它被定义为任何包含模式%### #的行,然后我们将替换为被引导和尾随的新行包围的行。

#3


1  

This might work for you (GNU sed):

这可能对您有用(GNU sed):

sed '/%%###/!b;G;i\\' file

For those lines that meet the criteria, append a newline from the hold space (the hold space by default contains a newline) and insert an empty line.

对于那些符合条件的行,从保持空间(默认情况下保持空间包含一个换行)追加一行,并插入空行。

Another way:

另一种方法:

sed -e '/%%###/!b;i\\' -e 'a\\' file

This time insert and then append empty lines.

这一次插入空行,然后追加空行。

N.B. The i and a must be followed by a newline, this can be achieved by putting them in separate -e invocations.

注意:i和a后面必须有一个换行符,这可以通过将它们放在独立的-e调用中来实现。

A third way:

第三种方法:

sed '/%%###/!b;G;s/.*\(.\)/\1&/' file

As in the first way, append a newline from the hold space, then copy it i.e. the last character of the amended current line, and prepend it to the current line.

和第一种方法一样,从保持空间中追加一条新行,然后将其复制,即修改后的当前行的最后一个字符,并将其前置到当前行。

Yet another way:

另一种方法:

sed '/%%###/{x;p;x;G}' file

Swap to the hold space, print the newline, swap back and append the newline.

交换到保持空间,打印换行,交换回来并附加换行。

N.B. If the hold space may not be empty (a previous, x,h,H,g or G command may have changed it) the buffer may be cleared before it is printed (p) by using the zap command z.

注意:如果保存空间可能不是空的(以前的、x、h、h、g或g命令可能已经更改了它),可以使用zap命令z在打印缓冲区之前清除缓冲区。

And of course:

当然:

sed  '/%%###/s/^\|$/\n/g' file

#4


0  

Personally I'd use a string instead of regexp comparison since there's no repexp characters in the text you want to match and if there were you wouldn't want them treated as such, and just print newlines around the string instead of modifying the string itself:

我个人会使用字符串而不是regexp比较,因为在文本中没有repexp字符要匹配,如果有的话,你不希望他们这样处理,只需要在字符串周围打印换行,而不是修改字符串本身:

awk '{print ($1=="^%%###" ? ORS $0 ORS : $0)}' file

The above will work with any awk in every shell on every UNIX box and is easily modified if you don't want multiple blank lines between consecutive %%### lines or don't want blank lines added if the existing surrounding lines are already blank or you need to do anything else.

上面的操作将在每个UNIX框上的每个shell中使用任何awk,如果您不想在连续的%###行之间添加多个空行,或者不希望在现有的周围行已经是空白的情况下添加空白行,或者您需要执行其他操作,那么就很容易修改。

#1


1  

With GNU sed:

GNU sed:

sed 's/.*%%###.*/\n&\n/' file

Output:

输出:

foobar
%%## Foo

%%### Bar

foobar

&: Refer to that portion of the pattern space which matched

&:指模式空间中匹配的部分

If you want to edit your file "in place" use sed's option -i.

如果你想编辑你的文件“到位”使用sed的选项-i。

#2


1  

It is cumbersome to directly add newlines via sed. But here is one option if you have perl available:

通过sed直接添加新行是很麻烦的。但如果您有perl可用,这里有一个选项:

$ foo.txt | perl -pe 's/(.*%%###.*)/\n$1\n/'

Here we capture every matching line, which is defined as any line containing the pattern %%### anywhere, and then we replace with that line surrounded by leading and trailing newlines.

在这里,我们捕获每一个匹配的行,它被定义为任何包含模式%### #的行,然后我们将替换为被引导和尾随的新行包围的行。

#3


1  

This might work for you (GNU sed):

这可能对您有用(GNU sed):

sed '/%%###/!b;G;i\\' file

For those lines that meet the criteria, append a newline from the hold space (the hold space by default contains a newline) and insert an empty line.

对于那些符合条件的行,从保持空间(默认情况下保持空间包含一个换行)追加一行,并插入空行。

Another way:

另一种方法:

sed -e '/%%###/!b;i\\' -e 'a\\' file

This time insert and then append empty lines.

这一次插入空行,然后追加空行。

N.B. The i and a must be followed by a newline, this can be achieved by putting them in separate -e invocations.

注意:i和a后面必须有一个换行符,这可以通过将它们放在独立的-e调用中来实现。

A third way:

第三种方法:

sed '/%%###/!b;G;s/.*\(.\)/\1&/' file

As in the first way, append a newline from the hold space, then copy it i.e. the last character of the amended current line, and prepend it to the current line.

和第一种方法一样,从保持空间中追加一条新行,然后将其复制,即修改后的当前行的最后一个字符,并将其前置到当前行。

Yet another way:

另一种方法:

sed '/%%###/{x;p;x;G}' file

Swap to the hold space, print the newline, swap back and append the newline.

交换到保持空间,打印换行,交换回来并附加换行。

N.B. If the hold space may not be empty (a previous, x,h,H,g or G command may have changed it) the buffer may be cleared before it is printed (p) by using the zap command z.

注意:如果保存空间可能不是空的(以前的、x、h、h、g或g命令可能已经更改了它),可以使用zap命令z在打印缓冲区之前清除缓冲区。

And of course:

当然:

sed  '/%%###/s/^\|$/\n/g' file

#4


0  

Personally I'd use a string instead of regexp comparison since there's no repexp characters in the text you want to match and if there were you wouldn't want them treated as such, and just print newlines around the string instead of modifying the string itself:

我个人会使用字符串而不是regexp比较,因为在文本中没有repexp字符要匹配,如果有的话,你不希望他们这样处理,只需要在字符串周围打印换行,而不是修改字符串本身:

awk '{print ($1=="^%%###" ? ORS $0 ORS : $0)}' file

The above will work with any awk in every shell on every UNIX box and is easily modified if you don't want multiple blank lines between consecutive %%### lines or don't want blank lines added if the existing surrounding lines are already blank or you need to do anything else.

上面的操作将在每个UNIX框上的每个shell中使用任何awk,如果您不想在连续的%###行之间添加多个空行,或者不希望在现有的周围行已经是空白的情况下添加空白行,或者您需要执行其他操作,那么就很容易修改。