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 位,但不能替换$
.我已经尝试过sed
gsubawk
但我尝试的似乎都不起作用。
答案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
)的能力,以根据需要生成适当数量的星号,而不需要“重复直到完成”循环。