替换数值

Replace the numeric value

如果文件在 excel format/csv

中,我们如何屏蔽数字数据
Input.xlsx/Input.csv 
Col1,Col2,Col3
A,B,-98.02
M,N,1003
P,Q,-1025.345

Output.xlsx/output.csv 
Col1,Col2,Col3
A,B,-78.14
M,N,1143
P,Q,-1245.745

我想动态地将每个数值屏蔽为不同的值。它必须用 shell

中的虚拟数字代替原始数据

这适用于 CSV 文件,不适用于 xlsx 文件:

gawk -F, 'BEGIN{ OFS=","}
          { for(i=1;i<=NF;i++){ 
               x=$i; 
               gsub(/[0-9.-]*/,"",x); 
               if(x==""){ $i=rand()*100 }
          } print [=10=] }'  Input.csv

在上面的脚本中,每个数值都被替换为 0 到 100 之间的数值(带小数)

输出(示例):

Col1,Col2,Col3
A,B,92.4046
M,N,59.3909
P,Q,30.6394

您可以用(几乎)任何东西替换 rand()*100 以获得另一个范围。

  • for(i=1;i<=NF;i++) 遍历当前行中的所有字段
  • gsub(/[0-9.-]*/,"",x) 将用空字符串 ("") 替换每个数字 (0-9),或 .-,当它是数字时有效地留下一个空字符串.
  • if(x=="")x 为空时,用随机值替换该字段。

注意:最后一块} print [=21=] }'也可以写成}}1',但我觉得用第一个选项更清楚。

编辑:保持负数为负,小数位数(大约)相同

创建 awk 脚本(即 replace.awk):

function rep(s) {
        sgn = s<0?-1:1
        nbc = int(log(sgn*s)/log(10))+1
        dec = (s-int(s)==0)?0:length(sgn*s-int(sgn*s))-2
        #print "DEBUG" sgn, nbc, dec, "%"nbc"."dec"f"
        return sprintf("%"nbc"."dec"f",sgn*rand()*(10**nbc))
        }

BEGIN{ OFS=","
        srand()
}
{ for(i=1;i<=NF;i++){
               x=$i;
               gsub(/[0-9.-]*/,"",x);
              if(x==""){ $i=rep($i) }
  }
}1

并执行:gawk -F, -f replace.awk Input.csv

输出应如下所示(示例):

Col1,Col2,Col3
A,B,-49.73
M,N,5577
P,Q,-551.278

本方案引入的变量:

  • sgn 数字的符号(+1 或 -1)
  • nbc 逗号前的数字(逗号 ==> 表示小数分隔符)
  • dec逗号后的位数(逗号==>表示小数点分隔符)