我有一个大约20列的“管道分隔”文件。我只想使用sha1sum哈希第一列,该列是类似于帐号的数字,并按原样返回其余列。
使用awk或sed做到这一点的最佳方法是什么?
Accountid|Time|Category|.....
8238438|20140101021301|sub1|...
3432323|20140101041903|sub2|...
9342342|20140101050303|sub1|...
上面是仅显示3列的文本文件的示例。只有第一列在其上实现了哈希函数。结果应为:
Accountid|Time|Category|.....
104a1f34b26ae47a67273fe06456be1fe97f75ba|20140101021301|sub1|...
c84270c403adcd8aba9484807a9f1c2164d7f57b|20140101041903|sub2|...
4fa518d8b005e4f9a085d48a4b5f2c558c8402eb|20140101050303|sub1|...
这是一个可以执行所需操作的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
为true时,打印整行(始终)这是encodeData
功能分解:
cmd
将数据馈送到sha1sum
getline
cmd
sha1sum
,因此我通过split
查看输出将其丢弃sha1sum
输出的第一个字段。使用您的数据,我得到以下信息:
Accountid|Time|Category|.....
104a1f34b26ae47a67273fe06456be1fe97f75ba|20140101021301|sub1|...
c84270c403adcd8aba9484807a9f1c2164d7f57b|20140101041903|sub2|...
4fa518d8b005e4f9a085d48a4b5f2c558c8402eb|20140101050303|sub1|...
通过调用awk.script data
(或./awk.script data
如果您bash)运行
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|...
该f[]
阵列由硬编码字段需要被散列的数量,为您的功能额外的参数使其本地和在每次调用所以总是零/零,则解耦脚本if
的函数getline意味着你不会回到以前的如果失败,则为成功值(请参阅http://awk.info/?tip/getline),其余的可能是更多的样式/首选项,并且性能有所改善。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句