除了Unix Shell中特定单词或模式的一部分之外,如何替换文本中的所有下划线

时间:2016-07-03 16:46:04

标签: shell unix sed

我有一个包含大量下划线的文件,我必须用空字符串替换它们,除了那些属于特定字符串usr_mstr的字符串。 我尝试过sed命令,它取代了下划线并排除了我提供的单词,但它也在紧跟下划线后替换了该字符!任何帮助将不胜感激..

echo "fname_sname_id_usr_mstr" | sed 's/_[^usr_mstr]//g'

预期产出:

fnamesnameidusr_mstr

实际输出:

fnamenamedusr_mstr

si已被替换)

3 个答案:

答案 0 :(得分:6)

这可能适合你(GNU sed):

sed -r 's/(usr_mstr)|_/\1/g' file

全局替换usr_mstr或自行替换_

答案 1 :(得分:5)

[^usr_mstr]是一个字符类,匹配任何不是usrmt或{的字符。 {1}}。

Perl支持“环顾”断言,所以你可以写:

_

即。如果之前没有echo "fname_sname_id_usr_mstr_x_usr_other_mstr_y_usrmstr_z" \ | perl -pe 's/(?<!usr)_//g;s/_(?!mstr)//g' ,则替换_,而不是usr

答案 2 :(得分:0)

单独使用标准sed BRE正则表达式无法解决这个问题。使用sed,您基本上需要替换&#34; usr_mstr&#34;使用占位符字符串,然后替换所有下划线,然后用&#34; usr_master&#34;替换占位符字符串。 ..

echo "fname_sname_id_usr_mstr" |
{ null="@#@"; sed "s/usr_mstr/$null/g; s/_//g; s/$null/usr_mstr/g" ;}

另一种方法是尝试awk:

echo "fname_sname_id_usr_mstr" |
awk -v s="usr_mstr" 'BEGIN{FS=OFS=s} {for(i=1; i<=NF; i++) gsub("_","",$i)}1'

只要s不包含扩展正则表达式中特殊的常规字符,哪个应该有效。