我必须根据特定密钥从JSON文件中提取数据。然后必须过滤数据(基于键值)并将其分成不同的固定宽度平面文件。我必须使用shell脚本开发解决方案。
由于数据只是键:值对,我可以通过处理JSON文件中的每一行来提取它们,检查类型并将值写入相应的固定宽度文件。
我的问题是输入的JSON文件大小约为5GB。我的方法非常基础,想知道是否有更好的方法可以使用shell脚本实现这一点?
示例JSON文件如下所示:
{"Type":"Mail","id":"101","Subject":"How are you ?","Attachment":"true"}
{"Type":"Chat","id":"12ABD","Mode:Online"}
以上是我需要处理的数据样本。
答案 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)
#!/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
}
#!/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