简体   繁体   English

Sed 处理多行模式

[英]Sed handle patterns over multiple lines

For example if I have a file like例如,如果我有一个像

yo@gmail.com, yo@
gmail.com yo@gmail
.com

And I want to replace the string yo@gmail.com .我想替换字符串yo@gmail.com If the file had the target string in a single line then we could've just used如果文件在一行中包含目标字符串,那么我们就可以使用

sed "s/yo@gmail.com/e@email.com/g" file

So, is it possible for me to catch patters that are spread between multiple line without replacing the \n?那么,我是否有可能在不替换 \n 的情况下捕获分布在多行之间的模式?

Something like this像这样的东西

e@email.com, e@
email.com e@email
.com

Thank you.谢谢你。

You can do this:你可以这样做:

tr -d '\n' < file | sed 's/yo@gmail.com/e@email.com/g'

This might work for you (GNU sed):这可能对你有用(GNU sed):

sed -E 'N;s/yo@gmail\.com/e@email.com/g
        h;s/(\S+)\n(\S+)/\1\2\n\1/;/yo@gmail\.com/!{g;P;D}
        s//\ne@email.com/;:a;s/\n(\S)(\S+)\n\S/\1\n\2\n/;ta
        s/(.*\n.*)\n/\1/;P;D' file

Append the following line to the pattern space. Append 下面一行到模式空间。

Replace all occurrences of matching email address in both the first and second lines.替换第一行和第二行中所有匹配的 email 地址。

Make a copy of the pattern space.复制模式空间。

Concatenate the last word of the first line with the first word of the second and keep the second line as is.将第一行的最后一个单词与第二行的第一个单词连接起来,并保持第二行不变。 If there is no match with the email address, revert the line, print/delete the first line and repeat.如果与 email 地址不匹配,则还原该行,打印/删除第一行并重复。

Otherwise, replace the match and re-insert the newline as of the length of the first word of the second line (deleting the first word of the second line too).否则,替换匹配并从第二行第一个单词的长度重新插入换行符(也删除第二行的第一个单词)。

Remove the newline used for scaffolding, print/delete the first line and repeat.删除用于脚手架的换行符,打印/删除第一行并重复。

NB The lines will not be of the same length as the originals if the replacement string length does not match the matching string length.注意 如果替换字符串长度与匹配字符串长度不匹配,则这些行的长度将与原始行的长度不同。 Also there has been no attempt to break the replacement string in the same relative split if the match and replacement strings are not the same length.如果匹配字符串和替换字符串的长度不同,也没有尝试在相同的相对拆分中中断替换字符串。


Alternative:选择:

echo $'yo@gmail.com\ne@email.com' |
sed -E 'N;s#(.*)\n(.*)#s/\\n\1/\\n\2/g#
       :a;\#\\n([^/])(.*)\\n(.)?(.*/g)#{s//\1\\n\2\3\\n\4/;H;ba}
       x;s/.//;s#\\n/g$#/g#gm;s#\\n/#/#;s/\./\\./g' |
sed -e 'N' -f - -e 'P;D' file

or:或者:

echo 's/yo@gmail.com/e@email.com/' |
sed -E 'h;s#/#/\\n#g;:a;H;s/\\n([^/])/\1\\n/g;ta;x;s/\\n$//mg;s/\./\\./g' |
sed -zf - /file

NB With the last alternative solution, the last sed invocation can be swapped for the first alternative solutions last sed invocation.注意使用最后一个替代解决方案,最后一个 sed 调用可以交换为第一个替代解决方案最后一个 sed 调用。

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

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