替换字符串后的字符

替换字符串后的字符
S-123-P Bash Pocket Ref.        2010    Cengage Learning    $55
E-P234  Python Pocket Ref.      2012    Cengage Learning    $45
55-MNP  Unix System Programming 2001    Sybex               $230

$我需要将不包括后的数字替换为$with *,因此输出需要为:

S-123-P Bash Pocket Ref.        2010    Cengage Learning    $**
E-P234  Python Pocket Ref.      2012    Cengage Learning    $**
55-MNP  Unix System Programming 2001    Sybex               $***

我已经能够替换最后一个数字或最后 2 位,但不能替换$.我已经尝试过sedgsubawk但我尝试的似乎都不起作用。

答案1

您可以利用sed不触及制表符/空格或字段意图的优势:

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

将每个替换($<zero-or-more-*>)[<non-*-character>]$<zero-or-more-*><plus-additional-*-added>\1*;是对定义\1中第一个匹配组的反向引用),直到所有s 替换为s。sed(...)<non-*-character>*


有点复杂,但如果您只想强制更改最后一个字段,您可以按以下方式使用该命令:

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

答案2

使用 awk / gsub - 假设我们可以替换最后一个字段中的任何十进制数字,只要它以$ie 开头,我们不需要处理类似以下内容123$45 -> 123$**

awk '$NF ~ /\$[0-9]+/ {gsub(/[0-9]/,"*",$NF)} 1' file

答案3

Perl 提供了一个很好的方法来做到这一点(如果你有的话):

perl -lpe 's/\$([0-9]*)/"\$" . "*" x length($1)/e'

这利用了使正则表达式替换的替换部分成为 Perl 表达式而不是固定字符串(标志/e)的能力,以根据需要生成适当数量的星号,而不需要“重复直到完成”循环。

相关内容