如何在sed替换期间保留字符数

时间:2014-12-12 19:20:35

标签: regex replace sed pcre

如何在sed中屏蔽以下数字?

account 123499029 - > account xxxxx9029

account 12345 - > account x2345

account 99999200193 - > account xxxxxxx0193

我正在使用PCRE正则表达式。

我知道我可以简单地使用固定数量的x替换带有

的前导数字

s/(account )\d+(\d{4})/\1xxx\2/g

但我无法弄清楚如何保留行数位数。

6 个答案:

答案 0 :(得分:1)

正常或默认sed使用BRE(基本正则表达式)。

$ echo 'account 123499029' | sed 's/\(account \)[0-9]\+\([0-9]\{4\}\)/\1xxx\2/'
account xxx9029

在基本sed中,捕获组将被定义为\(..\),并且sed不会支持\d  图案。您需要使用[0-9]代替\d。复制量词将在基本sed中定义为\{..\}

如有必要,请使用锚点。

$ echo 'account 123499029' | sed 's/^\(account \)[0-9]\+\([0-9]\{4\}\)$/\1xxx\2/'
account xxx9029

通过GNU sed,

$ echo 'account 123499029' | sed -r 's/^(account )[0-9]+([0-9]{4})$/\1xxx\2/'
account xxx9029

答案 1 :(得分:1)

AFAIK,sed 支持PCRE。相反,请检查perl的版本,以及您对自己的正则表达式所期望的内容:

$ perl -pe 's/(account )\d+(\d{4})/\1xxx\2/g' <<< 'account 123499029'
account xxx9029

答案 2 :(得分:1)

不幸的是,sed没有pcre正则表达式引擎。

with perl

要获得高级正则表达式功能,可以在命令行中使用perl:

perl -pe 's/(?:\G(?!\A)|account )\K\d(?=\d{4})/x/g' <<< 'account 123499029 account 12345 account 99999200193'

细节:

(?:                # open a non-capturing group
    \G             # position after the previous match or start of the string
    (?!\A)         # prevent to match the start of the string 
  |                # OR
    account[ ]     # entry for the first match 
)                  # close the non-capturing group
\K                 # remove all on the left from the match result
\d                 # the digit to replace
(?=\d{4})          # checks if there are 4 digits after
与sed

使用sed的方法包括使用标签和条件测试:

text='account 99999200193 account 12345 account 99999200193' 
echo $text | sed -r ':a;s/(account x*)[0-9]([0-9]{4})/\1x\2/g;ta'

细节:

:a          # define the label "a"
s/(account x*)[0-9]([0-9]{4})/\1x\2/g # replace the first digit after the "x"
                                      # followed by 4 other digits
ta          # if something is replaced go to label "a"

答案 3 :(得分:1)

这个perl命令行应该可以工作:

s='account 123499029'
perl -pe 's/\b(account )(\d*)(\d{4})\b/sub {return $1.'x' x length($2).$3;}->()/e' <<< "$s"
account xxxxx9029

s='account 12345'
perl -pe 's/\b(account )(\d*)(\d{4})\b/sub {return $1.'x' x length($2).$3;}->()/e' <<< "$s"
account x2345
  • 'x' x length($2)表达式填充字母x与第二个捕获组的长度一样多的时间。

答案 4 :(得分:1)

这可能适合你(GNU sed):

sed -r ':a;s/[0-9](X*[0-9]{4})/X\1/;ta' file

x和零个或多个x和4个数字替换一个数字,零个或多个x和4个数字,然后重复直到条件失败。

答案 5 :(得分:1)

这是awk

awk '{n=split($2,a,"");printf "%s ",$1;for (i=1;i<=n-4;i++) printf "x";for (i=n-3;i<=n;i++) printf a[i];print ""}' file
account xxxxx9029
account x2345
account xxxxxxx0193