регулярное выражение в sed для маскировки кредитной карты - PullRequest
3 голосов
/ 09 февраля 2010

Нам нужно замаскировать номера кредитных карт. Маскирование всех, кроме последних 4 цифр. Я пытаюсь использовать САС. Поскольку длина номера кредитной карты варьируется от 12 цифр до 19, я пытаюсь написать регулярное выражение. Следующий код получит строку. Если он содержит строку вида «CARD_NUMBER = 3737291039299199», он замаскирует первые 12 цифр. Проблема в том, как написать регулярное выражение для кредитной карты длиной от 12 до 19 цифр? Если я напишу другое выражение для 12 цифр, это не сработает. Это означает, что для кредитной карты из 12 цифр первые 8 цифр должны быть замаскированы для 15-разрядной кредитной карты первые 11 цифр должны быть замаскированы.

 while read data; do
    var1=${#data}

    echo "Length is "$var1
    echo $data | sed -e "s/CARD_NUMBER=\[[[:digit:]]\{12}/CARD_NUMBER=\[\*\*\*\*\*\*\*\*/g"
    done

Ответы [ 4 ]

5 голосов
/ 10 февраля 2010

Как насчет

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

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

4 голосов
/ 10 февраля 2010

Это делается одной командой sed без встроенного перевода строки:

sed -r 'h;s/.*([0-9]{4})/\1/;x;s/CARD_NUMBER=([0-9]*)([0-9]{4})/\1/;s/./*/g;G;s/\n//'

Если у вашего sed нет -r:

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

Если ваш sed нуждается -e:

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

Вот что он делает:

  • продублируйте число, чтобы оно находилось в пробелах и удерживайте пробел
  • захватить последние четыре цифры
  • поменять их в область удержания и целое число в пространство шаблона
  • захватить все, кроме последних четырех цифр
  • заменить каждую цифру символом маски
  • добавить последние четыре цифры из области удержания к концу маскированных цифр в пространстве образца (новая строка появляется бесплатно)
  • избавиться от новой строки
2 голосов
/ 10 февраля 2010

попробуйте, вам не нужно создавать сложные регулярные выражения

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

выход

$ ./shell.sh
************9199
1 голос
/ 10 февраля 2010

Я не большой гуру sed, и поэтому я не могу сделать это только одной командой, хотя, безусловно, есть способы. Но вот с двумя командами sed вот что я получил:

sed -e 's/CARD_NUMBER=\([0-9]*\)\([0-9]\{4\}\)/\1\
\2/' | sed -e '1s/./x/g ; N ; s/\n//'

Обратите внимание на встроенную новую строку .

Поскольку sed работает по строкам, сначала я делю номер карты на начальную часть и последние четыре цифры, разделяя их новой строкой (первая команда sed). Затем я маскирую начальную часть (1s/./x/g) и удаляю новую строку (N ; s/\n//).

Удачи!

...