用sed替换等长的文本

Mac*_*ers 6 regex linux bash sed

有没有办法用sed替换等长的其他东西(例如点,零等)的模式?像这样:

maci:/ san$ echo "She sells sea shells by the sea shore" | sed 's/\(sh[a-z]*\)/../gI'
.. sells sea .. by the sea ..
Run Code Online (Sandbox Code Playgroud)

("我"需要更新版本的sed来忽略大小写)
这很简单:以"sh"开头的单词被双点(..)替换但是如何使它成为这样的东西:... sells sea ...... by the sea .....

任何的想法?干杯!

Jon*_*ler 7

我怀疑你不能用标准来做sed,但你可以用Perl或其他更强大的正则表达式处理来做.

$ echo "She sells sea shells by the sea shore" |
> perl -pe 's/(sh[a-z]*)/"." x length($1)/gei'
... sells sea ...... by the sea .....
$
Run Code Online (Sandbox Code Playgroud)

该e改性剂是指替换模式是可执行的Perl脚本; 在这种情况下,它会重复.字符,因为匹配模式中有字符.所述g改性剂跨线重复; 该i改性剂是不区分大小写匹配.的-p选项的Perl打印在由指定的脚本的处理之后每一行-e的选择-替换命令.


Ken*_*ent 5

这个awk-oneliner为你做这个工作吗?

awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1' file
Run Code Online (Sandbox Code Playgroud)

测试您的数据:

kent$  echo "She sells sea shells by the sea shore"|awk '{for(i=1;i<=NF;i++)if($i~/^[Ss]h/)gsub(/./,".",$i)}1'
... sells sea ...... by the sea .....
Run Code Online (Sandbox Code Playgroud)


Mar*_*eal 5

一个老问题,但我发现了一个不错的、相对较短的单行 sed 解决方案:

sed ':a;s/\([Ss]h\.*\)[^\. ]/\1./;ta;s/[Ss]h/../g'
Run Code Online (Sandbox Code Playgroud)

通过在循环中一次替换一个字符来工作。

:a; 开始一个循环

s/\([Ss]h\.*\)[^\. ]搜索一个sh后跟任意数量的.s(我们目前完成的工作)后跟一个非点或空格字符(我们将要替换的内容)

/\1./;用我们迄今为止完成的工作加上另一个来代替它.。

ta; 如果我们做了任何替换,循环,否则......

s/[Ss]h/../gsh用两个.s替换s 并称它为一天。


pot*_*ong 3

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

sed -r ':a;/\b[Ss]h\S+/!b;s//\n&\n/;h;s/.*\n(.*)\n.*/\1/;s/././g;G;s/(.*)\n(.*)\n.*\n/\2\1/;ta' file
Run Code Online (Sandbox Code Playgroud)

在本质上; sh它复制以or开头的单词Sh,将每个字符替换为.,然后将新字符串重新插入到原始字符串中。当所有出现的搜索字符串都用完后,它会打印出该行。

替代:

sed -E 's/\S+/\n&/g;s#.*#echo "&"|sed "/^sh/Is/\\S/./g"#e;s/\n//g' file
Run Code Online (Sandbox Code Playgroud)