我试过这个
sed -i '' 's/[0-9]*<>/g'
但这没有用。
示例文件:
<Number1>
</Number8>
输出:
<Number>
</Number>
答案1
实际上,这真的很容易做到sed
。你只需一次性得到尽可能多的东西,然后再t
ry,t
ry 一遍:
sed -e :t -e 's/\(<[^<]*\)[0-9]\{1,\}\([^>]*>\)/\1\2/g;tt'
我尝试使用以下随机输入位:
<Number1>
234234 </Nu994845mb6er8>'
234234 <000000000000000000000000000000000000>>
<a1> 2 <34b5c> 6 7 def
结果是:
<Number>
234234 </Number>
234234 <>>
<a> 2 <bc> 6 7 def
<
正则表达式仅匹配 a和 a之间的至少一个数字>
。它继续用任何东西替换该数字序列,直到它无法再成功地这样做为止。这就是 est 命令的目的t
。
否则你可以做到没有类似这样的循环:
sed 's/^/>/;s/\(>[^<>]*\)*[0-9]*/\1/g;s/.//' <<\INPUT
<Number1>
234234 </Nu994845mb6er8>'
234234 <000000000000000000000000000000000000>>
<a1> 2 <34b5c> 6 7 def
INPUT
输出
<Number>
234234 </Number>'
234234 <>>
<a> 2 <bc> 6 7 def
它总是会跳过任何一个,>
直到遇到<
- 所以它只影响<[^<>]*>
组。看这如果你有兴趣知道为什么。
答案2
以下作品:
sed -i 's/\(<[^0-9>]*\)[0-9]*\([^0-9]*>\)/\1\2/g' filename
答案3
您要么需要围绕替换命令的循环(在 sed 和 perl 中都可能),要么需要嵌套替换命令(仅限 perl)。我更喜欢后一种方法;这有点更一般:
perl -pe 's/\<([^>]*)\>/do{$a = $1; $a =~ s,\d,,g; "\<" . $a . "\>"}/ge;'
输入示例:
<a1> 2 <34b5c> 6 7 def
输出:
<a> 2 <bc> 6 7 def
说明:该-p
选项表示我们要逐行读取文件,对每一行执行脚本,然后打印结果(就像在 sed 中一样);-e
意味着下一个参数是要执行的脚本。
本质上,该脚本只是一个替换命令:我们查找<
,后跟任意数量的非>
字符,最后是>
。e
尾部后面的修饰符表示/
替换命令的一个特殊功能:它的替换部分不是要打印的字符串,而是要执行的命令序列。在此命令序列中,我们首先将<
和之间的字符串>
(即$1
)分配给一个新变量$a
,然后执行另一个替换命令,$a
将每个数字(\d
)替换为空,最后返回<
,然后是修改后的字符串,然后是>
。修饰符g
(在结尾/
和结尾之后,
)意味着应该对每个匹配的字符串执行替换命令,而不仅仅是第一个字符串。
如果开口<
和相应的>
可以在不同的行中,比如说,
<abc1
opt="def">
添加选项-0777
(即perl -0777 -pe '...'
),以便 perl 在处理之前读取整个文件,而不是逐行工作(吸食模式)。
答案4
短 sed 方式
sed 's/<\([^>]\+\)[0-9]\+>/<\1>/g' file