Регулярное выражение с использованием sed - PullRequest
0 голосов
/ 17 февраля 2010

Раньше я задавал этот вопрос. Но почему-то я не дал полный ввод. Вход - это файл журнала. Я пытаюсь использовать sed для замены всех, кроме последних четырех цифр, номера кредитной карты.

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

Это выражение определенно работает, но оно заменяет не только номера кредитных карт, но и некоторые другие данные (где цифры больше 4). Входная запись, содержащая номер кредитной карты, имеет формат:

"CARD_NUMBER=[6362229292929290]"

Так что мне нужно заменить запись вышеупомянутого формата. Так что вышеупомянутая запись должна быть преобразована в

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

Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 17 февраля 2010

Если номер кредитной карты имеет 16 цифр, я бы попробовал

sed -e :a -e "s/[0-9]\{12\}\([0-9]\{4\}\)/\*\*\*\*\*\*\*\*\*\*\*\*\1/;ta" $today_temp_log
0 голосов
/ 18 февраля 2010

Вы можете использовать поля адреса внутри sed, чтобы ограничить замену строками, которые соответствуют определенному шаблону.Так что просто добавьте /CARD_NUMBER=/ в начало вашего выражения, давая

sed -e :a -e "/CARD_NUMBER=/s/[0-9]\([0-9]\{4\}\)/\*\1/;ta" $today_temp_log
0 голосов
/ 17 февраля 2010

Исходя из моего ответа здесь , это замаскирует начало номера и оставит метку, скобки и последние четыре цифры для номеров карт практически любого числа цифр:

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//'

Если вам нужно проверить, что общее количество цифр попадает только в заданный диапазон, это тоже можно сделать.

Edit:

Вот несколько способов:

Пропускать номера без изменений, которые являются слишком длинными или слишком короткими:

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]
0 голосов
/ 17 февраля 2010
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]
0 голосов
/ 17 февраля 2010
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]

вышеописанное работает для любой длины цифры номера карты

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...