sed:封锁后追加

时间:2019-01-27 05:11:32

标签: regex sed append

我对sed很陌生,我发现的一切都在这里,在那儿。

我有一个文本文件,其中包含如下所示的块:

#start
a
b
c


#whatever
…

很明显,这是简化版本。我想在#start块的末尾添加一行以给我:

#start
a
b
c
d

#whatever
…

我可以通过以下方式找到该块:

sed -n '/^#\s*start/,/^$/ p' data.txt

所以我认为这是正确的方向。但是:

  • 所选内容包括我不需要的空行
  • 我不知道如何在比赛结束后添加另一行

5 个答案:

答案 0 :(得分:3)

使用sed:

sed '/#start/,/^$/ s/^$/d/;' file
  • /#start/,/^$/:搜索以#start开头并以空行结尾的块
  • s/^$/d/:将匹配的空白行替换为d

如果要在空白行之前添加字符串:

sed '/#start/,/^$/{/^$/{s//d/;G;};}' file

答案 1 :(得分:0)

对于GNU sed,请尝试以下操作(再次更新,有一个小错误):

sed '/^#\s*start/{x;s/.*/d/;x;be};/^\s*#[a-zA-Z]*/{x;G;x;s/.*//;x;};/^\s*$/{x;};:e'

例如:

$ cat file                                                               
#start                                                                   
a                                                                        
b                                                                        
c                                                                        


#whatever                                                                
...                                                                      

$ cat file2                                                              
#start                                                                   
a                                                                        
b                                                                        
c                                                                        
#whatever                                                                
...                                                                                                       
$ sed '/^#\s*start/{x;s/.*/d/;x;be};/^\s*#[a-zA-Z]*/{x;G;x;s/.*//;x;};/^\s*$/{x;};:e' file  
#start                                                                   
a                                                                        
b                                                                        
c                                                                        
d                                                                        


#whatever                                                                
...                                                                      

$ sed '/^#\s*start/{x;s/.*/d/;x;be};/^\s*#[a-zA-Z]*/{x;G;x;s/.*//;x;};/^\s*$/{x;};:e' file2 
#start                                                                   
a                                                                        
b                                                                        
c                                                                        
d                                                                        
#whatever                                                                
...      

sed命令将洗排not-so-empty空行(仅空格行)。但是我觉得对你没关系吧?
想法是使用hold space保留需要追加的内容(此处为d),并在时间到时追加。
xhold space(当前的读入行)交换pattern space

顺便说一句,如果有多个#start块,它将添加到所有块中,如果您不希望这种行为,请发表评论。

答案 2 :(得分:0)

您可以像这样简单地使用awk

awk -v RS= '/#start/{$0 = $0 ORS "d\n"} 1' file

如果#start不在文件顶部,则需要执行以下操作:

awk -v RS= '/#start/{$0 = $0 ORS "d"} {$0 = $0 ORS} 1' file

*这会删除每个块之间的所有换行符。

结果

#start
a
b
c
d

#whatever
…

答案 3 :(得分:0)

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

@Component({
  selector: 'foo-header'
})
export class ContentHeaderComponent {
}

## content-header.component.html
...some markup...
<ng-content select="[header-icon]"></ng-content>
...some more markup...    

## foo.component.html
<foo-header>
   <i-chevron-down header-icon></i-foo-icon>
</foo-header>

关注sed '/^#start/,/^\s*$/!b;/^\s*$/c\d' file 开头的行和空行之间的行范围。如果该行为空,请将其更改为#start

d取消匹配,而!则没有占位符,无法进行sed的任何进一步处理。

为进行比较,请注意这些解决方案的行为,第一种情况是在空行之前插入b,第二种情况是在空行之后插入d

d

答案 4 :(得分:-1)

在任何UNIX盒子上的任何外壳中都有任何awk:

$ awk 'BEGIN{RS=""; ORS="\n\n"; FS=OFS="\n"} $1=="#start"{$(NF+1)="d"} 1' file
#start
a
b
c
d

#whatever
…

与当前接受的sed解决方案不同,即使目标字符串包含regexp元字符,即使要添加的字符串包含反向引用,并且即使其中任何一个包含定界符(/),也可以使用上述方法进行细微修改以基于输入块的第二,第三或任何其他行的值进行更改,而不是仅基于第一行或除第一行之外,还可以进行细微修改以在输入中间添加或修改任何行块。简而言之,这是一种极为优越的方法。