使用sed的正则表达式

时间:2010-02-17 17:04:22

标签: regex shell sed

过去我问过这个问题。但不知怎的,我没有给出完整的输入。输入是一个日志文件。我正在尝试使用sed替换除了最后四位数的信用卡号。

sed -e :a -e "s/[0-9]\([0-9]\{4\}\)/\*\1/;ta" $today_temp_log

这个表达肯定有效,但它不仅取代了信用卡号码,还取代了一些其他数据(数字大于4)。包含信用卡号的输入记录格式为:

"CARD_NUMBER=[6362229292929290]"

所以我需要替换上面格式的记录。所以上面的记录应该转换为

"CARD_NUMBER=[************9290]"

提前致谢。

5 个答案:

答案 0 :(得分:2)

假设信用卡号码有16位数字,我会尝试

sed -e :a -e "s/[0-9]\{12\}\([0-9]\{4\}\)/\*\*\*\*\*\*\*\*\*\*\*\*\1/;ta" $today_temp_log

答案 1 :(得分:0)

var1="CARD_NUMBER=[6362229292929290]"
IFS="="
set -- $var1
cardnumber=$2
result=$(echo $cardnumber | awk 'BEGIN{OFS=FS=""}{for(i=1;i<=NF-5 ;i++){ $i="*"} }1')
echo "$1=[$result"

输出

$ ./shell.sh
CARD_NUMBER=[*************9290]

或者使用awk

var1="CARD_NUMBER=[6362229292929290]"
echo $var1 | awk 'BEGIN{ OFS=FS="=" }
{
    gsub(/\[|\]/,"",$2)
    m=split($2,s,"")
    for(i=1;i<=m-4;i++){ s[i]="*" }
    str=$1 OFS "["
    for(i=1;i<=m;i++){ str=str s[i] }
    str=str "]"
}END{ print str } '

输出

$ ./shell.sh
CARD_NUMBER=[************9290]

以上适用于任何数字长度的卡号

答案 2 :(得分:0)

sed -e :a -e "s/\(CARD_NUMBER=\[\**\)[0-9]\([0-9]\{4\}\)/\1\*\2/;ta"

测试用例:

$ echo "blah=[123456789012345678] CARD_NUMBER=[6362229292929290] CARD_NUMBER=[13456]" | sed -e :a -e "s/\(CARD_NUMBER=\[\**\)[0-9]\([0-9]\{4\}\)/\1\*\2/;ta"
blah=[123456789012345678] CARD_NUMBER=[************9290] CARD_NUMBER=[*3456]

答案 3 :(得分:0)

根据我的回答here,这将掩盖数字的开头,并留下几乎任意位数的卡号的标签,括号和最后四位数字:

sed -e 'h' -e 's/.*\([0-9]\{4\}\)/\1/' -e 'x' -e 's/\(.*\[\)\([0-9]*\)\([0-9]\{4\}\)./\1\2/' -e 's/[0-9]/*/g' -e 'G' -e 's/\n//'

如果您需要验证总位数仅在给定范围内,也可以这样做。

修改

以下是两种方式:

传递太长或太短的数字:

sed -e '/.*\[[0-9]\{12,19\}\]/!b' -e 'h' -e 's/.*\([0-9]\{4\}\)/\1/' -e 'x' -e 's/\(.*\[\)\([0-9]*\)\([0-9]\{4\}\)./\1\2/' -e 's/[0-9]/*/g' -e 'G' -e 's/\n//'
CARD_NUMBER=[12345678] yields CARD_NUMBER=[12345678]  
CARD_NUMBER=[123456789012] yields CARD_NUMBER=[********9012]
CARD_NUMBER=[12345678901234567890] yields CARD_NUMBER=[12345678901234567890]

使用不同的掩码字符掩盖太长或太短的数字的所有数字:

sed -e '/.*\[[0-9]\{12,19\}\]/!{s/[0-9]/x/g;b}' -e 'h' -e 's/.*\([0-9]\{4\}\)/\1/' -e 'x' -e 's/\(.*\[\)\([0-9]*\)\([0-9]\{4\}\)./\1\2/' -e 's/[0-9]/*/g' -e 'G' -e 's/\n//'
CARD_NUMBER=[12345678] yields CARD_NUMBER=[xxxxxxxx]  
CARD_NUMBER=[123456789012] yields CARD_NUMBER=[********9012]  
CARD_NUMBER=[12345678901234567890] yields CARD_NUMBER=[xxxxxxxxxxxxxxxxxxxx]

答案 4 :(得分:0)

您可以使用sed中的地址字段将替换限制为与特定模式匹配的行。所以只需将/CARD_NUMBER=/添加到表达式的开头,然后给出

sed -e :a -e "/CARD_NUMBER=/s/[0-9]\([0-9]\{4\}\)/\*\1/;ta" $today_temp_log