Bash sed 替换直到行尾

Bash sed replace until end of line

我有以下输入文件:

this is text
     identifier {
         item /directory/file_1234 
some more text 
item /directory/file_1234 other line text
     identifier {
         item /directory/98_76file
other line

我想用 /directory/file_ABC

替换行 identifier { 之后的字符串 item /directory/*

我试过了

cat input | sed ':a;N;$!ba;s/    identifier {\n        item \/directory\/.*$/    identifier {\n        newitem \/directory2\/file_ABC/g'

但它会在第一次出现后删除这些行

this is text
    identifier {
        newitem /directory2/file_ABC

假设你想替换这两个事件,你可以使用这个sed

$ sed '/identifier {/{N;s~\(.*\n[^[:alpha:]]*\).*~newitem /directory/file_ABC~}' input_file
this is text
     identifier {
         newitem /directory/file_ABC
some more text
item /directory/file_1234 other line text
     identifier {
         newitem /directory/file_ABC
other line

您的问题来自模式的最后 .*$:在 multi-line 模式下,它一直匹配到模式 space 的末尾。尝试(使用 GNU sed 测试):

$ sed -E ':a;N;$!ba;s!((^|\n) +identifier \{\n +)item /directory/[^\n]*!newitem /directory2/file_ABC!g' input
this is text
     identifier {
         newitem /directory2/file_ABC
some more text 
item /directory/file_1234 other line text
     identifier {
         newitem /directory2/file_ABC
other line

注意:使用cat喂养sed是一个anti-pattern。只需 sed 'script' file.

注意:使用 ! 作为替换命令的字段分隔符而不是 / 可以避免转义,使用 -E 选项可以简化更多。

这可能适合您 (GNU sed):

sed -E '/identifier \{/{n;s#(/directory/).*#file_ABC#;}' file

通过设置 -E 打开扩展正则表达式。

匹配包含 identifier { 的行并打印然后获取下一行。

如果该行与 /directory/ 匹配,则将其替换为 file_ABC