/ / JSON-Datei mit fester Breite - Json, Shell, Unix, Skript

JSON zu fester Breite Datei - Json, Shell, Unix, Skripting

Ich muss Daten aus JSON-Datei abhängig extrahierenauf einem bestimmten Schlüssel. Die Daten müssen dann gefiltert werden (basierend auf dem Schlüsselwert) und in verschiedene Flachdateien mit fester Breite getrennt werden. Ich muss eine Lösung mit Shell-Scripting entwickeln.

Da die Daten nur das Schlüssel-Wert-Paar sind, kann ich sie extrahieren, indem ich jede Zeile in der JSON-Datei verarbeite, den Typ prüfe und die Werte in die entsprechende Datei mit fester Breite schreibe.

Mein Problem ist, dass die JSON-Eingabedatei ungefähr 5 GB groß ist. Meine Methode ist sehr einfach und würde gerne wissen, ob es einen besseren Weg gibt, dies mit Shell-Scripting zu erreichen?

Die JSON-Beispieldatei würde wie folgt aussehen:

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

Das obige Beispiel zeigt, welche Art von Daten ich verarbeiten muss.

Antworten:

0 für die Antwort № 1

Probieren Sie es aus:

#!/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"
}

Ich habe Annahmen gemacht, die auf den Beispieldaten basierenunter der Voraussetzung. Diese Annahmen basieren auf vielen Annahmen, die möglicherweise geändert werden müssen, wenn die Daten stark von den angezeigten Daten abweichen. Insbesondere funktioniert dieses Skript nicht ordnungsgemäß, wenn die Datenwerte oder Feldnamen Doppelpunkte, Kommas, Anführungszeichen oder geschweifte Klammern enthalten Wenn dies ein Problem ist, ist dies einer der Hauptgründe, warum ein richtiger JSON-Parser verwendet werden sollte. Wenn es meine Aufgabe wäre, würde ich mich an diesem Punkt stark zurücklehnen, um die Erlaubnis zu erhalten, die richtigen Werkzeuge zu verwenden.

Dies gibt Zeilen mit dem Typ "Mail" in eine Datei namens "Mail.fixed.out" aus und geben "Chat" in "Chat.fixed.out" usw.

Der Feldname "Type" und der Feldwert ("Mail" usw.) werden nicht als Inhalt ausgegeben. Dies kann geändert werden.

Andernfalls werden sowohl die Feldnamen als auch die Werte ausgegeben. Dies kann geändert werden.

Die Feldbreiten sind alle auf 15 Zeichen festgelegt und mit Leerzeichen aufgefüllt, ohne Trennzeichen. Die Feldbreite kann geändert werden usw.

Lassen Sie mich wissen, wie nahe das an das kommt, wonach Sie suchen, und ich kann einige Anpassungen vornehmen.


0 für die Antwort № 2

Perl-Skript

#!/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
}

entsprechendes Shell-Skript

#!/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

Beispiel:

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