Perl (App::RecordStream) 向记录添加一个字段,该字段是其他字段子集的唯一哈希值(md5 或类似值)

Perl (App::RecordStream) to add a field to a record that is a unique hash value (md5 or similar) for a subset of the other fields

我正在编写一个 *nix 处理管道,它以复杂的嵌套 JSON 开始,以 CSV 结束。管道中的最后一步是:

 ... | recs-tocsv > my_csv_file.csv

现在,上面的 ... 是平换行分隔 JSON 看起来像这样(所有值都是字符串,并非所有键都在所有记录中,但每条记录至少有 1 prefix_键):

{"key1" : "value1", "key2" : "value2", "prefix_key3" : "value3", "prefix_key4" : "value4"}
{"key1" : "value5", "key2" : "value6", "prefix_key3" : "value7", "prefix_key4" : "value8"}

我想为每条记录添加一个新字段,它是所有以 prefix 开头的键的串联值的唯一哈希值(md5 或类似值)。输出应如下所示(仍为紧凑形式,但为清楚起见,此处使用空格格式化):

{"key1" : "value1", 
 "key2" : "value2", 
 "prefix_hash" : "0b129fd4ae0587f4e606c6a78ef977a1", 
 "prefix_key3" : "value3", 
 "prefix_key4" : "value4"}
{"key1" : "value5", 
 "key2" : "value6", 
 "prefix_hash" : "cf59a16edf48bcb0d0566ba3dc19843a",
 "prefix_key3" : "value7", 
 "prefix_key4" : "value8"}

其中 prefix_hash 是 "value3;value4"、"value7;value8" 等的 md5sum(或等效值)

我正在寻找可以在 recs-xformrecs-eval 调用中使用的 App::RecordStream 命令语法。 (采用 STDIN 并在 STDOUT 上生成正确输出的 Perl 片段也可以)。我在使用多个键并将多个操作链接在一起时遇到困难(使用 prefix 获取所有键的值,加入一个字符串,计算 md5sum,将 md5sum 设置为新键的值)。任何能够在 (Linux) 命令行上相对快速地产生正确输出的东西都可以。

暂时忽略关于 App::RecordStream 的部分,我试图提炼出您问题的症结所在,如果我理解正确,下面的代码将满足您的要求:

use strict;
use warnings;

use Digest::MD5 qw(md5_hex);
use JSON::XS;

while (<DATA>) {
    chomp;

    my $obj = decode_json($_);
    my $key = join(';', map { $obj->{$_} } grep { /^prefix/ } sort(keys(%$obj)));
    $obj->{prefix_hash} = md5_hex($key);

    print encode_json($obj), "\n";
}

__DATA__
{"key1" : "value1", "key2" : "value2", "prefix_key3" : "value3", "prefix_key4" : "value4"}
{"key1" : "value5", "key2" : "value6", "prefix_key3" : "value7", "prefix_key4" : "value8"}

输出(换行pretty-printed):

{
    "key2": "value2",
    "key1": "value1",
    "prefix_key4": "value4",
    "prefix_hash": "55f506f7e49469e44f807f8b4f55a5ff",
    "prefix_key3": "value3"
}
{
    "key2": "value6",
    "key1": "value5",
    "prefix_key4": "value8",
    "prefix_hash": "fdb804ef84534068168f146bcbebf30e",
    "prefix_key3": "value7"
}

如果要对STDIN或文件列表进行操作,请将while (<DATA>)更改为while (<>)并删除底部的__DATA__块。