简体   繁体   English

使用sed命令替换多行

[英]Replacing multiple line using sed command

I have a text file file.log contains following text 我有一个文本文件file.log包含以下文本

file.log file.log

ab
cd
ef

I want to replace "ab\\ncd" with "ab\\n" and the final file.log should look like this: 我想将“ ab \\ ncd”替换为“ ab \\ n”,最终的file.log应该如下所示:

ab

ef

This is the sed command I am using but it couldn't recognize the newline character to match the pattern: 这是我使用的sed命令,但无法识别换行符以匹配模式:

sed -i 's/\(.*\)\r   \(.*\)/\1\r/g' file.log

with 3 character space after '\\r' but no change is made with this. '\\ r'之后有3个字符的空格,但是对此没有任何改变。

\\(.*\\) - This matches any character(.) followed by 0 or more (*) of the preceding character \\r - For newline \\1 - Substitution for the first matching pattern. \\(.*\\) -匹配任何字符(。),后跟0或多个(*)前一个字符\\r对于换行符\\1替换第一个匹配模式。 In this case, it's 'ab' 在这种情况下,它是“ ab”

Can you help me out what's wrong with the above command. 您能帮我解决以上命令的问题吗?

Sed processes the input file line by line. sed逐行处理输入文件。 So can't do like the above . 所以不能像上面那样。 You need to include N , so that it would append the next line into pattern space. 您需要包括N ,以便它将下一行追加到模式空间中。

$ sed 'N;s~ab\ncd~ab\n~g' file
ab

ef

The issue is that, the sed is a stream editor, which reads line by line from the input file 问题是, sed是流编辑器,它从输入文件中逐行读取

So when it reads line 所以当它读线

ab

from the input file, it doesnt know whether the line is followed by a line 从输入文件中,它不知道行后是否有一行

cd

When it reads the line cd it sed will habe removed the line ab from the pattern space, this making the pattern invalid for the current pattern space. 当它读取cd行时,它会从模式空间中删除ab行,这使得该模式对于当前模式空间无效。

Solution

A solution can be to read the entire file, and append them into the hold space, and then replace the hold space. 一种解决方案是读取整个文件,并将它们附加到保留空间中,然后替换保留空间。 As

$ sed -n '1h; 1!H;${g;s/ab\ncd/ab\n/g;p}' input
ab

ef

What it does 它能做什么

  • 1h Copies the first line into the hold space. 1h将第一行复制到保留空间。

  • 1!H All lines excpet the first line ( 1! ) appends the line to the hold space. 1!H所有行都取代第一行( 1! ),将行追加到保留空间。

  • $ matches the last line, performs the commands in {..} $匹配最后一行,执行{..}的命令

  • g copies the contents of hold space back to pattern space g将保留空间的内容复制回模式空间

  • s/ab\\ncd/ab\\n/g makes the substitution. s/ab\\ncd/ab\\n/g进行替换。

  • p Prints the entire patterns space. p打印整个图案空间。

A couple of other options: 其他几个选择:

perl -i -0pe 's/^ab\n\Kcd$//mg' file.log

which will change any such pattern in the file 这将更改文件中的任何此类模式

If there's just one, good ol' ed 如果只有一个,好醇” ed

ed file.log <<END_SCRIPT
/^ab$/+1 c

.
wq
END_SCRIPT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM