如何在Linux上打印带有掩码值的环境名称?



我想使用标准工具和bash打印Linux上的所有环境变量。如果变量长度大于5,我需要看到环境名称和掩码变量,最后3个字符可见(qwerty->***rty),如果小于5(或等于5),则屏蔽值为1个可见字符(zxc->**c)。

的例子:

FOO=qwerty
BAR=asdfghjkl
BAZ=zxc

我希望这个命令打印:

FOO=***rty
BAR=******jkl
BAZ=**c

原值和掩码的长度在这里是一样的

此刻,我试图使用这个awk命令来实现这一点,但它只处理了一些情况,用3*替换所有单词,并将值切到最后3个字符(我对awk不是很好,所以也许它可以实现更好):

env | awk -F= '{ if(length($2)>5) {printf("%s=***%sn", $1, substr($2, length($2)-2))} }'

bash的解决方案可能是:

#!/bin/bash
env |
while IFS='=' read -r name value; do
n=$((${#value} > 5 ? -3 : ${#value} > 0 ? -1 : 0))
head=${value:0:n}
printf '%s=%s%sn' "$name" "${head//?/'*'}" "${value:n}"
done

注意:在shell编程中,通过while read循环读取行是低效的。我假设env命令发出的输出足够小,这种低效率并不明显。对于大的输入,您不应该使用此技术。

用awk gensub:

试试这个脚本
#!/bin/bash
env | awk -F= '{
name=$1;
value=$2;
if (length(value) > 5) {
mask=gensub(/./,"*","g",substr(value,1,length(value)-3));
value=mask substr(value,length(value)-2);
} else {
mask=gensub(/./,"*","g",substr(value,1,length(value)-1));
value=mask substr(value,length(value));
}
print name "=" value;
}'

如果您想偷懒,不关心星号的正确数量,您可以这样做:

$ env | sed 's/=(...*)(...)/=***2/'

如果星号必须是正确的总数,则可以使用awk。但是,使用等号作为字段分隔符并不是正确的方法,因为单行可能包含多个等号:

$ env | awk '{i=index($0,"="); s=substr($0,i+1);l=length(s)}(l>5){x=substr(s,1,l-3); gsub(/./,"*",x); print substr($0,1,i) s1 substr(s,l-2); next}1'

这里是一个稍微紧凑的awk版本,它处理大于5个字符的环境字符串,将值中除最后三个字符外的所有字符替换为'*'。在字符串少于5个字符的情况下,除最后一个字符外的所有字符都被替换。这与您的示例输出相匹配,尽管您没有提供包含4或5个字符的示例。

基本上awk脚本构建一个"***"字符正确数目的mask和一个"..."的带有替换字符数目的动态正则表达式re,并调用sub()进行替换,例如

awk -F= '
{
l = length($2)
mask = ""
re = ""
for (i=0;i<(l>5?l-3:l-1);i++) {
mask = mask "*"
re = re "."
}
mask = "=" mask
re = "=" re
sub (re, mask)
print
}' file

使用/输出示例

$ awk -F= '
> {
>   l = length($2)
>   mask = ""
>   re = ""
>   for (i=0;i<(l>5?l-3:l-1);i++) {
>     mask = mask "*"
>     re = re "."
>   }
>   mask = "=" mask
>   re = "=" re
>   sub (re, mask)
>   print
> }' << eof
> FOO=qwerty
> BAR=asdfghjkl
> BAZ=zxc
> eof
FOO=***rty
BAR=******jkl
BAZ=**c

此方法预先生成"*" x 2,400字符串,并通过substr()-ing代替regex,因此除非您的数据值超过2,400字节/字符,否则这应该足够了。

mawk 'BEGIN { FS = OFS = "="; _=(_=(_="*")_ _)_
gsub(__,_,_) gsub(__,_,_); _ +=(_^= ___ = _)+_ } 
$NF = sprintf("%.*s%s",__ -=_^((_+_) <= (__ = length($NF))), ___, substr($NF, ++__))' 
FOO=***rty
BAR=******jkl
BAZ=**c

最新更新