使用 AWK 的随机字母

Random Letters using AWK

我正在使用 AIX 服务器中的 AWK 函数创建一个 sh 代码来屏蔽敏感数据。

Input:

CustomerName|somedata|phonenumber|Address
Roly|xyz|1234|London

Output:

CustomerName|somedata|phonenumber|Address
Atrm|xyz|8546|Xdfdtt

注意:CustomerName、Phonenumber、Address 是敏感信息,因此我只更改这些。

我想保留相同的字典值,直到我决定更改字典(用什么替换什么)。

我在 AIX 中的代码。这仅适用于 AIX 系统(我希望如此)

set -A randomalpha
set -A alphabets a b c d e f g h i j k l m n o p q r s t u v w x y z
set -A numbers 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9  0 1 2 3 4 5 6 7 8 9
randomalpha=`cat /dev/urandom| tr -dc 'A-Z'|head -c 26`
randonumber=`cat /dev/urandom| tr -dc '0-9'|head -c 26`

i=0
echo $randomalpha | awk -v ORS="" '{ gsub(/./,"&\n") ; print }' | \
while read char
do
   randomalpha[i]="$char"
   print "$char"
   ((i=i+1))
done

print ${randomalpha[4]}
print ${alphabets[25]}

integer max=1400
integer i=1

while [[ $i -lt $max ]]
do
# $(echo value of is : $i >> $file)
 #   echo value i: $i
  #  (( i = i + 1 ))
b=""
echo "Please enter your name:" 
read name

i=0

echo $name | awk -v ORS=" " '{ gsub(/./,"&\n") ; print }' | \
while read char
do
   name[i]="$char"   

   j=0
    while [ $j -le 36 ] 
    do

    if [[ "$char" == ${alphabets[j]} ]];then
        #print  "matched here:"${alphabets[j]}"matched here:"${randomalpha[j]} 
        b=$b${randomalpha[j]}

        if [ -z "${char}" ];then
             b=$b${randomalpha[j]}" "
        fi

        if [[ "$char" == ${numbers[j]+} ]];then
           print "$char"
        #print  "matched here:"${alphabets[j]}"matched here:"${randomalpha[j]} 
        b=$b${randonumber[j]}

        if [ -z "${numbers}" ];then
             b=$b${randonumber[j]}" "
        fi
        fi

    fi
    ((j=j+1))
    done
   ((i=i+1))
done

print $b

done

我所做的是

我为 A-Z 分配了一个随机字符,然后匹配每个字符的输入值并替换为该字符的字典值。

用简单的术语来说,让我们说

实际值:ABCD 随机生成:XUTY

所以只要它找到 A,它就会被 X 替换。 我知道这是一个错误的代码,但我正在尝试这个选项来证明它是可能的。

有人可以阐明使用几行 AWK 以比大代码更简单的方式实现结果吗?

当我处理 20GB 的文件时,这段代码要慢得多

谢谢!

如果我明白你想做什么,这将适用于任何系统上的任何 awk,并且比你的 shell 脚本快 运行 个数量级:

$ cat tst.awk
function shuffle(oldStr,        newStr,len,array,i,j,t) {
    # logic copied from https://www.rosettacode.org/wiki/Knuth_shuffle#AWK
    # and tweaked to operate on a string as input instead of an array.
    len = length(oldStr)
    for (i=1; i<=len; i++) {
        array[i] = substr(oldStr,i,1)
    }

    for (i = len; i > 1; i--) {
        # j = random integer from 1 to i
        j = int(i * rand()) + 1

        # swap array[i], array[j]
        t = array[i]
        array[i] = array[j]
        array[j] = t
    }

    for (i=1; i<=len; i++) {
        newStr = newStr array[i]
    }
    return newStr
}

BEGIN {
    srand()

    ordrLets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    randLets = shuffle(ordrLets)
    ordrDigs = "0123456789"
    randDigs = shuffle(ordrDigs)

    ordrChars = ordrLets ordrDigs
    randChars = randLets randDigs

    numChars = length(ordrChars)
    for (charNr=1; charNr<=numChars; charNr++) {
        oldChar = substr(ordrChars,charNr,1)
        newChar = substr(randChars,charNr,1)
        map[tolower(oldChar)] = tolower(newChar)
        map[toupper(oldChar)] = toupper(newChar)
        # Uncomment this to print the mappings to stderr:
        # print oldChar, newChar | "cat>&2"
    }

    split("1 3 4", fldIdx2nr)

    FS = OFS = "|"
}

NR==1 { print; next }
{
    for (fldIdx in fldIdx2nr) {
        fldNr  = fldIdx2nr[fldIdx]
        oldStr = $fldNr
        newStr = ""
        numChars = length(oldStr)
        for (charNr=1; charNr<=numChars; charNr++) {
            oldChar = substr(oldStr,charNr,1)
            newChar = (oldChar in map ? map[oldChar] : oldChar)
            newStr  = newStr newChar
        }
        $fldNr = newStr
    }
    print
}

.

$ cat file
CustomerName|somedata|phonenumber|Address
Roly|xyz|1234|London

$ awk -f tst.awk file
CustomerName|somedata|phonenumber|Address
Tcnj|xyz|2397|Ncoyco

我假设您实际上希望每个字母都映射到一个唯一的字母,这与您的原始代码所做的不同。如果情况并非如此,并且您不介意将多个原始字母映射到同一个最终字母,那么您可以使用对 rand() 的简单调用来创建每个单独的映射,而不是使用 shuffle() 函数的主要算法。