【问题标题】:Replace/delete special characters within matched strings in sed替换/删除 sed 中匹配字符串中的特殊字符
【发布时间】:2013-05-31 02:57:04
【问题描述】:

我有一个包含类似行的文件

I want a lot <*tag 1> more <*tag 2>*cheese *cakes.

我正在尝试删除 &lt;&gt; 内的 * 而不是外部。标签可能比上面更复杂。例如,&lt;*better *tag 1&gt;

我尝试了/\bregex\b/s/\*//g,它适用于标签 1,但不适用于标签 2。那么如何让它也适用于标签 2?

非常感谢。

【问题讨论】:

  • 可以嵌套&lt;&gt;吗?
  • 就我而言,不会有嵌套的。干杯。

标签: regex sed


【解决方案1】:

强制 Perl 解决方案:

perl -pe '$_ = join "",
        map +($i++ % 2 == 0 ? $_ : s/\*//gr),
        split /(<[^>]+>)/, $_;' FILE

追加:

perl -pe 's/(<[^>]+>)/$1 =~ s(\*)()gr/ge' FILE

【讨论】:

  • 伟大的 perl 单行。我也 +1。
【解决方案2】:

标签中只有一个星号的简单解决方案

sed 's/<\([^>]*\)\*\([^>]*\)>/<\1\2>/g'

如果你能拥有更多,你可以使用 sed goto 标签系统

sed ':doagain s/<\([^>]*\)\*\([^>]*\)>/<\1\2>/g; t doagain'

其中doagain 是循环标签,t doagain 是条件跳转到标签doagain。参考sed手册:

t label

 Branch to label only if there has been a successful substitution since the last 
 input line was read or conditional branch was taken. The label may be omitted, in 
 which case the next cycle is started.

【讨论】:

  • 感谢循环解决方案。 :-)
  • 您要求 sed 解决方案 :) 很高兴它对您有所帮助;)
【解决方案3】:

awk 可以解决您的问题:

awk '{x=split($0,a,/<[^>]*>/,s);for(i in s)gsub(/\*/,"",s[i]);for(j=1;j<=x;j++)r=r a[j] s[j]; print r}' file

更易读的版本:

 awk '{x=split($0,a,/<[^>]*>/,s)
       for(i in s)gsub(/\*/,"",s[i])
       for(j=1;j<=x;j++)r=r a[j] s[j]
       print r}' file

用你的数据测试:

kent$  cat file
I want a lot <*tag 1> more <*tag 2>*cheese *cakes. <*better *tag X*>

kent$  awk '{x=split($0,a,/<[^>]*>/,s);for(i in s)gsub(/\*/,"",s[i]);for(j=1;j<=x;j++)r=r a[j] s[j]; print r}' file
I want a lot <tag 1> more <tag 2>*cheese *cakes. <better tag X>

【讨论】:

  • 我不熟悉split的4参数版本,第四个参数是什么?
猜你喜欢
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 2014-03-30
  • 1970-01-01
  • 2017-03-24
  • 2016-11-30
相关资源
最近更新 更多