JSON到固定宽度的文件

时间:2011-02-28 18:27:52

标签: json shell unix scripting

我必须根据特定密钥从JSON文件中提取数据。然后必须过滤数据(基于键值)并将其分成不同的固定宽度平面文件。我必须使用shell脚本开发解决方案。

由于数据只是键:值对,我可以通过处理JSON文件中的每一行来提取它们,检查类型并将值写入相应的固定宽度文件。

我的问题是输入的JSON文件大小约为5GB。我的方法非常基础,想知道是否有更好的方法可以使用shell脚本实现这一点?

示例JSON文件如下所示:

{"Type":"Mail","id":"101","Subject":"How are you ?","Attachment":"true"}
{"Type":"Chat","id":"12ABD","Mode:Online"}

以上是我需要处理的数据样本。

2 个答案:

答案 0 :(得分:0)

尝试一下:

#!/usr/bin/awk
{
    line = ""
    gsub("[{}\x22]", "", $0)
    f=split($0, a, "[:,]")
    for (i=1;i<=f;i++)
        if (a[i] == "Type")
            file = a[++i]
        else
            line = line sprintf("%-15s",a[i])
    print line > file ".fixed.out"
}

我根据提供的样本数据做出了假设。如果数据与您所显示的数据有很大差异,那么可能需要更改这些假设。特别是,如果数据值或字段名称包含冒号,逗号,引号或大括号,则此脚本将无法正常工作。如果这是一个问题,那么应该使用正确的JSON解析器的主要原因之一。如果这是我的任务,我会在这一点上努力争取获得使用适当工具的许可。

将具有“Mail”类型的行输出到名为“Mail.fixed.out”的文件,并将“Chat”输入到“Chat.fixed.out”等。

“类型”字段名称和字段值(“邮件”等)不作为内容的一部分输出。这可以改变。

否则,输出字段名称和值。这可以改变。

字段宽度全部固定为15个字符,用空格填充,没有分隔符。可以改变字段宽度等。

让我知道这与您正在寻找的内容有多接近,我可以做一些调整。

答案 1 :(得分:0)

perl脚本

#!/usr/bin/perl -w
use strict;
use warnings;

no strict 'refs'; # for FileCache
use FileCache; # avoid exceeding system's maximum number of file descriptors
use JSON;

my $type;
my $json = JSON->new->utf8(1); #NOTE: expect utf-8 strings

while(my $line = <>) { # for each input line
    # extract type
    eval { $type = $json->decode($line)->{Type} };
    $type = 'json_decode_error' if $@;
    $type ||= 'missing_type';

    # print to the appropriate file
    my $fh = cacheout '>>', "$type.out";
    print $fh $line; #NOTE: use cache if there are too many hdd seeks
}

相应的shell脚本

#!/bin/bash
#NOTE: bash is used to create non-ascii filenames correctly

__extract_type()
{
    perl -MJSON -e 'print from_json(shift)->{Type}' "$1"
}

__process_input()
{
    local IFS=$'\n'
    while read line; do # for each input line
        # extract type
        local type="$(__extract_type "$line" 2>/dev/null ||
            echo json_decode_error)"
        [ -z "$type" ] && local type=missing_type

        # print to the appropriate file
        echo "$line" >> "$type.out"
    done
}

__process_input

示例:

$ ./script-name < input_file
$ ls -1 *.out
json_decode_error.out
Mail.out