如何更改包含模式的行的第一次出现?

Jul*_*gio 9 sed

我需要找到第一次出现模式的行,然后我需要用一个全新的行替换整行。

我发现这个命令替换了模式的第一次出现,但不是整行:

sed -e "0,/something/ s//other-thing/" <in.txt >out.txt
Run Code Online (Sandbox Code Playgroud)

如果 in.txt 是

one two three
four something 
five six
something seven
Run Code Online (Sandbox Code Playgroud)

结果我进入了out.txt:

one two three
four other-thing
five six
something seven
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试修改此代码以替换整行时,如下所示:

sed -e "0,/something/ c\COMPLETE NEW LINE" <in.txt >out.txt
Run Code Online (Sandbox Code Playgroud)

这是我在 out.txt 中得到的:

COMPLETE NEW LINE
five six
something seven
Run Code Online (Sandbox Code Playgroud)

你知道为什么第一行丢失了吗?

M. *_*din 10

c\命令删除第一个匹配地址到第二个匹配地址之间的所有行,当与 2 个地址一起使用时,并c\在匹配第二个地址时打印出后面指定的文本。如果输入中没有与第二个地址匹配的行,它只会删除第一个匹配地址到最后一行之间的所有行(包括)。由于您只想替换一行,因此不应c\在地址范围内使用该命令。在c\后面紧跟着在正常使用一个新的行字符。的0,/regexp/地址范围是一个GNUsed扩展,这将尝试匹配regexp在第一输入线也一样,其中从不同1,/regexp/在这方面。因此,GNU 中的正确命令sed可能是

sed '0,/something/{/something/c\
COMPLETE NEW LINE
}' < in.txt
Run Code Online (Sandbox Code Playgroud)

或简化为 Sundeep 指出的

sed '0,/something/{//c\
COMPLETE NEW LINE
}' < in.txt
Run Code Online (Sandbox Code Playgroud)

或单线,

sed -e '0,/something/{//cCOMPLETE NEW LINE' -e '}' < in.txt
Run Code Online (Sandbox Code Playgroud)

如果不需要文字换行符。

正如potong所指出的,这种单线也有效:

sed '0,/something/!b;//cCOMPLETE NEW LINE' in.txt
Run Code Online (Sandbox Code Playgroud)


pot*_*ong 6

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

sed '1!b;:a;/something/!{n;ba};cCOMPLETE NEW LINE' file
Run Code Online (Sandbox Code Playgroud)

设置一个仅从第一行开始运行的循环。

在循环中,如果在当前行中没有找到关键字,则打印当前行,获取下一行并重复直到文件末尾或找到匹配项。

找到匹配项后,将当前行的内容更改为所需的结果。

注意该c命令以与该d命令相同的方式终止对 sed 命令的任何进一步处理。

如果输入中有关键字匹配后的行,则在 sed 循环开始时对地址的否定将捕获这些行并导致它们打印出来而不再进行进一步处理。

替代:

sed 'x;/./{x;b};x;/something/h;//cCOMPLETE NEW LINE' file
Run Code Online (Sandbox Code Playgroud)

或者(特定于 GNU 和 bash):

sed $'0,/something/{//cCOMPLETE NEW LINE\n}' file
Run Code Online (Sandbox Code Playgroud)