我有一个包含行的文件像替换/在sed
I want a lot <*tag 1> more <*tag 2>*cheese *cakes.
我试图删除*内<>
但不应超出删除匹配的字符串中的特殊字符。标签可能比以上更复杂。例如,<*better *tag 1>
。
我试过/\bregex\b/s/\*//g
,它适用于标签1,但不适用于标签2.那么我怎样才能使它适用于标签2呢?
非常感谢。
我有一个包含行的文件像替换/在sed
I want a lot <*tag 1> more <*tag 2>*cheese *cakes.
我试图删除*内<>
但不应超出删除匹配的字符串中的特殊字符。标签可能比以上更复杂。例如,<*better *tag 1>
。
我试过/\bregex\b/s/\*//g
,它适用于标签1,但不适用于标签2.那么我怎样才能使它适用于标签2呢?
非常感谢。
强制性Perl的解决方案:
perl -pe '$_ = join "",
map +($i++ % 2 == 0 ? $_ : s/\*//gr),
split /(<[^>]+>)/, $_;' FILE
附加:
+1的单行划线器 –
伟大的perl单线程。我也是+1。 – ToonZ
简单的解决方案,如果您有标签只有一个星号
sed 's/<\([^>]*\)\*\([^>]*\)>/<\1\2>/g'
如果你可以有更多的,你可以使用SED转到标签系统
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.
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的四参数版本,什么是第四个参数? – Lorkenpeist
你能有嵌套'<>'? –
在我的情况下,不会有嵌套的<>。干杯。 – ToonZ