/ / JSON do pliku o stałej szerokości - json, shell, unix, scripting

JSON do pliku o stałej szerokości - json, shell, unix, scripting

W zależności od tego muszę wyodrębnić dane z pliku JSONna konkretny klucz. Dane muszą być następnie filtrowane (na podstawie wartości klucza) i rozdzielane na różne pliki o stałej szerokości. Muszę opracować rozwiązanie przy użyciu skryptów powłoki.

Ponieważ dane to tylko para klucz: wartość, mogę je wyodrębnić, przetwarzając każdą linię w pliku JSON, sprawdzając typ i zapisując wartości w odpowiednim pliku o stałej szerokości.

Moim problemem jest to, że wejściowy plik JSON ma rozmiar około 5 GB. Moja metoda jest bardzo prosta i chciałbym wiedzieć, czy istnieje lepszy sposób na osiągnięcie tego za pomocą skryptów powłoki?

Przykładowy plik JSON wyglądałby jak poniżej:

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

Powyższe jest przykładem rodzaju danych, które muszę przetworzyć.

Odpowiedzi:

0 dla odpowiedzi № 1

Wypróbuj to:

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

Założyłem założenia na podstawie przykładowych danychopatrzony. Wiele opiera się na tych założeniach, które mogą wymagać zmiany, jeśli dane różnią się znacznie od tego, co pokazałeś. W szczególności skrypt ten nie będzie działać poprawnie, jeśli wartości danych lub nazwy pól zawierają dwukropki, przecinki, cudzysłowy lub nawiasy klamrowe Jeśli jest to problem, jest to jeden z głównych powodów, dla których należy użyć właściwego parsera JSON. Gdyby to było moje zadanie, nacisnąłem mocno w tym punkcie, aby uzyskać pozwolenie na użycie odpowiednich narzędzi.

Wyprowadza wiersze, które mają typ „Mail” do pliku o nazwie „Mail.fixed.out” i wpisz „Chat” do „Chat.fixed.out” itd.

Nazwa pola „Typ” i wartość pola („Poczta” itp.) Nie są wyświetlane jako część zawartości. Można to zmienić.

W przeciwnym razie wyświetlane są zarówno nazwy pól, jak i wartości. Można to zmienić.

Wszystkie szerokości pól są ustalone na 15 znaków, wypełnione spacjami, bez ograniczników. Szerokość pola można zmienić itp.

Daj mi znać, jak blisko jest tego, czego szukasz i mogę dokonać pewnych zmian.


0 dla odpowiedzi nr 2

skrypt 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
}

odpowiedni skrypt powłoki

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

Przykład:

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