Скрипт модуляризации awk для маскировки конфиденциальных данных в файле с разделителями - PullRequest
1 голос
/ 18 октября 2019

У меня есть файл с разделителями в следующем формате:

text1|12345|email@email.com|01-01-2020|1

Учитывая, что все поля являются конфиденциальными данными,я написал следующую команду awk, чтобы замаскировать первое поле со случайными данными.

awk -F'|' -v cmd="strings /dev/urandom | tr -dc '0-9' | fold -w 5" 'BEGIN {OFS=FS} {cmd | getline a;$1=a;print}' source.dat > source_masked.dat

Если я хочу замаскировать дополнительные поля, я добавляю следующее.

awk -F'|' -v cmd1="strings /dev/urandom | tr -dc '0-9' | fold -w 5" -v cmd2="strings /dev/urandom | tr -dc 'A-Za-z0-9' | fold -w 7" 'BEGIN {OFS=FS} {cmd | getline a; cmd2 | getline b;$2=b}' source.dat > source_masked.dat

Как масштабироватьесли я хочу замаскировать 100 столбцов с разными типами данных?

По сути, я хочу взять из файла конфигурации следующее:

column number, datatype, length

и использовать его в awk для генерации команди сценарий замены динамически.

Не могли бы вы посоветовать то же самое?

Я переписал тот же самый принятый ответ на awk, поскольку для маскировки больших файлов с помощью bash потребовалось много времени.

Код для того же:

function mask(datatype, precision) {
    switch (datatype) {
        case "string":
            command = "strings /dev/urandom | tr -dc '[:alpha:]' | fold -w "
            precision
            break
        case "alphaNumeric":
            command = "strings /dev/urandom | tr -dc '[:alnum:]' | fold -w "
            precision
            break
        case "number":
            command = "strings /dev/urandom | tr -dc '[:digit:]' | fold -w "
            precision
            break
        default:
            command = "strings /dev/urandom | tr -dc '[:alnum:]' | fold -w "
            precision
    }
    command | getline v
    return v
}

BEGIN {
    while ((getline line < "properties.conf") > 0) {
        split(line, a, ",")
        col = a[1]
        type = a[2]
        len = a[3]
        masks[col] = type " "
        len
    }
    IFS = "|"
    OFS = "|"
} {
    for (i = 1; i <= NF; i++) {
        if (masks[i] != "") {
            split(masks[i], m, " ")
            $i = mask(m[1], m[2])
        }
    }
    print
}

Ответы [ 2 ]

0 голосов
/ 18 октября 2019

Один из подходов заключается в чтении файла конфигурации маски в массив, проиндексированный по номеру столбца.

Затем чтение файла данных построчно. поместите каждое поле во второй массив. Затем для каждого элемента массива маски рандомизируйте соответствующее поле данных. Когда все поля обновлены, выведите новую строку и перейдите к следующей строке.

Нужно ли это делать в awk? Это может быть проще / быстрее сделать в нативном bash:

#!/bin/bash

declare    mask_file=masks.conf
declare    input_file=input.dat
declare    output_file=output.dat

function create_mask() {
# ${1} is type, ${2} is length
  case ${1} in
    string ) ;;
    date   ) ;;
    number ) ;;
    *      ) ;;
  esac
}

while read column type length; do
  masks[${column}]="${type} ${length}"
done < ${mask_file}

IFS='|'
while read -a data; do
  for column in ${!masks[@]}; do
    data[${column}]=$(create_mask ${masks[${column}]})
  done
  echo "${data[*]}"   # Uses IFS as output separator.
done < ${input_file} > ${output_file}

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

0 голосов
/ 18 октября 2019

Вместо этого вы можете использовать встроенную функцию rand для генерации случайного числа.

Определить ассоциативный массив со списком полей, которые вы хотитемаска.

Например, вот пример кода, который будет маскировать поле 1 и 4

awk -F\| '
        BEGIN {
                A_mask_field[1]
                A_mask_field[4]
        }
        {
                for ( i = 1; i <= NF; i++ )
                {
                        if ( i in A_mask_field )
                                $i = sprintf( "%d", rand() * length($i)  * 100000 )
                }
        }
        1
' OFS=\| file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...