/ / JSON до файлу з фіксованою шириною - json, shell, unix, scripting

JSON для файлу з фіксованою шириною - json, shell, unix, scripting

Я повинен витягти дані з файлу JSON залежнона певній клавіші. Дані потім повинні бути відфільтровані (на основі значення ключа) і розділені на різні фіксовані плоскі файли з шириною. Я повинен розробити рішення, використовуючи сценарії оболонки.

Оскільки дані просто ключ: значення пари, я можу витягти їх, обробляючи кожен рядок у файлі JSON, перевіряючи тип і записуючи значення у відповідний файл фіксованої ширини.

Моя проблема полягає в тому, що вхідний файл JSON має розмір приблизно 5 Гб. Мій метод дуже базовий і хотів би знати, чи є кращий спосіб досягти цього за допомогою сценаріїв оболонки?

Зразок JSON-файлу виглядатиме так:

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

Вище наведений приклад даних, які потрібно обробити.

Відповіді:

0 для відповіді № 1

Дайте це спробуйте:

#!/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.fixed.out" і введіть "Чат" до "Chat.fixed.out" і т.д.

Поле "Тип" і значення поля ("Пошта" тощо) не виводяться як частина вмісту. Це можна змінити.

В іншому випадку виводяться імена і значення полів. Це можна змінити.

Ширини поля закріплені на 15 символів, пропущені пробілами без розділювачів. Ширину поля можна змінювати тощо.

Дозвольте мені знати, наскільки це близьке до того, що ви шукаєте, і я можу внести деякі корективи.


0 для відповіді № 2

скрипт 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
}

відповідний сценарій оболонки

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