首页 > 解决方案 > 模块化 awk 脚本以屏蔽分隔文件中的敏感数据

问题描述

我有以下格式的分隔文件:

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
}

标签: bashawk

解决方案


您可以改用内置的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

推荐阅读