如何用“*”替换特殊字符“$”之后的每个数字

如何用“*”替换特殊字符“$”之后的每个数字

我有一个包含如下数据的文件

文件中的数据:

axbnx $56 ghjas $78$
axbnx $5** ghjas $ 
axbnx $006 ghjas $$678 

需要以下形式的输出:

axbnx $** ghjas $**$
axbnx $*** ghjas $ 
axbnx $*** ghjas $$*** 

我的代码:[它不工作]

sed -E 's/$[[:digit:]]/*/g'

尝试在这个模拟器上工作:https://rextester.com/l/bash_online_compiler

答案1

perl

$ perl -pe 's/\$\K\d+/$&=~s|.|*|gr/ge' ip.txt
axbnx $** ghjas $**$
axbnx $*** ghjas $ 
axbnx $*** ghjas $$*** 
  • \$\K\d+匹配前面有$字符的数字(\K将防止$成为 中匹配部分的一部分$&
  • $&=~s|.|*|gr将匹配部分的每个字符替换为*
  • e允许在替换部分使用 Perl 代码的标志

您还可以使用perl -pe 's/\$\d+/$&=~tr|0-9|*|r/ge'

答案2

使用 GNU awk 将第三个参数传递给 match() 和 gensub():

$ awk '{while ( match($0,/(.*)(\$[0-9]+)(.*)/,a) ) $0=a[1] gensub(/[0-9]/,"*","g",a[2]) a[3]} 1' file
axbnx $** ghjas $**$
axbnx $*** ghjas $
axbnx $*** ghjas $$***

答案3

调整一个小变化关于我对你之前提出的问题的回答,将[^*](非星号字符)更改为[0-9]数字,您可以这样做:

sed -E ':a s/(\$\**)[0-9]/\1*/; ta' infile

我不确定是否要保留诸如$***123不被转换或不如注释中指出的模式,但为了防止这种情况,您可以将$这些模式之后的第一个字符更改为类似的内容,$<Uniq-character-or-string>*然后对其余模式进行更改,使用以下命令将该模式恢复到之前的状态:

sed -E ':a s/\$\*/$Uniq*/;ta;
        :b s/(\$\**)[0-9]/\1*/; tb;
        :c s/\$Uniq\*/$*/; tc;
' infile

答案4

以下程序将连续将模式“后跟一位或多位数字”awk中的数字替换为:$*

awk '{do {$0=gensub(/(\$\**)[[:digit:]]/,"\\1*","g");} while ($0~/\$\**[[:digit:]]/)}1' input.txt

它通过将模式“$后跟零个或多个*数字,然后一个数字”替换为“数字之前的所有内容,然后一个数字*”(gensub()调用)来实现这一点,并循环直到不再出现搜索模式。

调用中的语法gensub()指示awk搜索模式$、零个或多个*以及一位数字,并将该数字(括在括号中)之前的所有内容存储到“捕获组”中。在此模式的替换文本中,此“捕获组”由 引用\\1并按原样复制,但省略了数字并*代之以文字。

相关内容