这里有一个可执行的awk脚本,可以做到你想要的效果:
#!/usr/bin/awk -f
BEGIN { FS=OFS="|" }
FNR != 1 { $1 = encodeData( $1 ) }
47
function encodeData( fld ) {
cmd = sprintf( "echo %s | sha1sum", fld )
cmd | getline output
close( cmd )
split( output, arr, " " )
return arr[1]
}
这是工作流程的详细说明:
- 将输入和输出字段分隔符设置为
|
- 当行不是第一行(标题行)时,将
$1
重新分配为编码值
- 当
47
为真(总是)时,打印整个行
这是
encodeData
函数的详细说明:
- 创建一个
cmd
来向
sha1sum
提供数据
- 将其提供给
getline
- 关闭
cmd
- 在我的系统上,
sha1sum
之后有额外的信息,所以我通过
split
来丢弃它们
- 返回
sha1sum
输出的第一个字段。
使用您的数据,我得到以下结果:
Accountid|Time|Category|.....
104a1f34b26ae47a67273fe06456be1fe97f75ba|20140101021301|sub1|...
c84270c403adcd8aba9484807a9f1c2164d7f57b|20140101041903|sub2|...
4fa518d8b005e4f9a085d48a4b5f2c558c8402eb|20140101050303|sub1|...
通过调用awk.script data
(如果您使用bash,则为./awk.script data
)来运行。
由EdMorton编辑:很抱歉修改了您的脚本,但上面的脚本是正确的方法,但需要进行一些调整,以使其更加健壮,这比试图在注释中描述它们要容易得多:
$ cat tst.awk
BEGIN { FS=OFS="|" }
NR==1 { for (i=1; i<=NF; i++) f[$i] = i; next }
{ $(f["Accountid"]) = encodeData($(f["Accountid"])); print }
function encodeData( fld, cmd, output ) {
cmd = "echo \047" fld "\047 | sha1sum"
if ( (cmd | getline output) > 0 ) {
sub(/ .*/,"",output)
}
else {
print "failed to hash " fld | "cat>&2"
output = fld
}
close( cmd )
return output
}
$ awk -f tst.awk file
104a1f34b26ae47a67273fe06456be1fe97f75ba|20140101021301|sub1|...
c84270c403adcd8aba9484807a9f1c2164d7f57b|20140101041903|sub2|...
4fa518d8b005e4f9a085d48a4b5f2c558c8402eb|20140101050303|sub1|...
< p >
f[]
数组将您的脚本与硬编码需要进行哈希处理的字段数量分离,函数的附加参数使它们在每次调用时始终为局部变量,
getline
中的
if
意味着如果失败,则不会返回先前的成功值(请参见
http://awk.info/?tip/getline),其余部分可能更多地涉及样式/偏好以及稍微的性能改进。