JSON pipes в короби

    Чим більше я пишу однострочнікі в короби, тим більше я приходжу до двох важливих ідей:
     
  1. Це дуже потужний засіб для «безпосереднього програмування», тобто вказівки комп'ютеру, що робити.
  2.  
  3. Велика частина однострочнікі присвячена grep / awk / cut / tr, які якимось чином виколупують і приводять в людський вигляд висновок попередніх утиліт.
  4.  
При тому, що модель pipe'ов чудова, абсолютно брудні хакі з вилову потрібних полів у виведенні в другому пункті («а ось тут ми можемо виділити потрібне нам за характерною коми за допомогою awk-F, '{print $ 2}'… ) роблять процедуру спірної по задоволенню, і вже точно нечитаною.
 
Ще одна серйозна проблема: при тому, що шелл дає досить багато ідіом з функціонального програмування, в ньому немає ідіоми фільтрації списку по результату виконання зовнішньої програми. Тобто "грепнуть" список ми можемо. А ось залишити в списку тільки ті елементи, для яких якась програма повернула "успіх" — ні.
 
При цьому є ворожа і не дуже добре написана середу — powershell (вінди). У яких взяли хорошу ідею (пайпи передають не текст, а об'єкти), але зіпсували її двома речами:
     
  1. неергономічними консоллю виндов (Shift-PgUp де, а?)
  2.  
  3. пропозицією піти і вивчити. net для того, щоб нормально з методами працювати.
  4.  
 
Хочеться мати об'єкти в пайпе в теплому ламповому лінуксових Шеллі. З hand-candy (мало друкувати), eye-candy (приємно дивитися) і загальної ергономічністю процесу використання. Ще хочеться мати можливість поєднувати "новий підхід" зі старим, тобто звичайним текстовим pipe'ом.
 
 Ідея
Треба написати набір інструментів, які дозволять в pipe-style оперувати з структурованими даними. Очевидним вибором є XML JSON.
Нам потрібно:
     
  1. Утиліти, які візьмуть типові формати на вхід і конвертує їх у json.
  2.  
  3. Утиліти, які дозволять в pipe'е маніпулювати з json'ом.
  4.  
  5. Утиліти, які приведуть json в "звичайний" формат.
  6.  
У цьому випадку людина не бачитиме json на екрані, але буде мати можливість працювати з ним.
 
 Для затравки
(Для розуміння я буду писати довгі імена утиліт, в реальному житті це будуть короткі скорочення, тобто не json-get-object, а щось типу jgo або jg)
 
Виводить тільки файли, для яких file зумів визначити тип:
 
ls -la | ls2json | json-filter 'filename' --exec 'file {} >/dev/null' | json-print

 
Викачує з деякого сайту токен для авторизації, виколупує його з json'а і виставляє в змінні середовища оточення, після чого завантажує список і відфільтрувавши по регекспу поле "автор" викачує всі url'и:
 
curl mysite/api.json | env `json-get-to-env X-AUTH-TOKEN`;curl -H X-AUTH-TOKEN $X-AUTH-TOKEN mysite/api/list.json | json-filter --field 'author' --rmatch 'R.{1,2}dal\d*' | json-get --field 'url' | xargs wget

 
Парсит висновок find-ls, сортує по полю size, вирізає з масиву елементи з 10 по 20, виводить їх в csv.
 
find . -ls | ls2josn | json-sort --field 'size' | json-slice [10:20] | json2csv

 
 
 Термінологія
 input'и
Основне завдання — з messy-виводу зробити json-цукерочку. Важливо: мати опцію для обробки некоректного введення: а) ігнорувати, б) зупиняти pipe з помилкою.
 
Приклади:
Generic:
     
  • line2json — конвертує звичайний висновок в масив рядків, де рядок відповідає рядку (line to string).
  •  
  • words2json — аналогічно, але по "словами".
  •  
  • csv2json — конвертує cvs в об'єкт, дозволяючи зазначений елемент призначити ключем.
  •  
  • lineparse2json — конвертує рядок в об'єкт, розділяючи її за вказаними символам. Нагадує awk-F: '{print $ 1, $ 2}',
  •  
 
app-specific:
 
     
  • ls2json (на вибір — або робить ls, або бере висновок ls) і структурує його як масив об'єктів, де кожен об'єкт — файл з купою полів. Може бути, навіть більшою, ніж вміє ls (звичайні та розширені атрибути lsattr, вся інформація про инод, дати створення і т.д.)
  •  
  • ps2json — аналогічно, за списками процесів
  •  
  • lsof2json — список об'єктів, що описують додатки, що використовують файл.
  •  
  • openfiles2json — список fd, відкритих додатком (/ proc / PID / fd), з вбудованою фільтрацією, наприклад, "files only", "ignore / dev / null". У об'єктах з мережних сокетам відразу ж додається вся інформація — порти / ip.
  •  
  • iptables2json — виводить поточні налаштування iptables у формі json
  •  
File-specific:
Читають файл, виводять його в json'е.
 
     
  • syslog2json
  •  
  • ini2json
  •  
  • conf.d2json
  •  
  • sysv2json, upstart2json
  •  
 нативні json-перетворення
Найсмачніше — нативні маніпуляції над json'ом. Аналогічно, повинні мати опції обробки »не json'а -" ігнорувати »/« зупинятися ».
     
  • json-filter — фільтрує об'єкти / масиви за заданими критеріями.
  •  
  • json-join — робить з двох json'ов один зазначеним методом.
  •  
  • json-sort — сортує масив об'єктів за вказаною полю
  •  
  • json-slice — вирізає шматочок з масиву
  •  
  • json-arr-get — повертає елемент з масиву
  •  
  • json-obj-get — повертає задане поле / поля зазначеного об'єкта
  •  
  • json-obj-add — додає об'єкт
  •  
  • json-obj-del — видаляє об'єкт
  •  
  • json-obj-to-arr — виводить ключі або задане поле об'єктів як масив
  •  
  • json-arr-to-obj — перетворює масив в об'єкт формуючи ключ по заданому ознакою.
  •  
  • json-uniq — видаляє повторювані елементи в масиві (або виводить тільки повторювані)
  •  
(Додати за смаком і потребам)
 output'и
Приводять json в человекочітаемий вигляд:
 
     
  • json2fullpath — перетворюють json в нотацію рядків виду key1.key2 [3]. key4 = «foobar»
  •  
  • json2csv
  •  
  • json2lines — виводять масив по елементу на рядок, якщо всередині об'єкти — розділяючи їх пробілами на рядку.
  •  
  • json2keys — виводить ключі об'єкта
  •  
  • json2values ​​- виводить тільки значення об'єкта
  •  
 
 iterator'и
Фактично, розширення xargs на json:
 
     
  • json-keys-iterate — запускає зазначені команди для кожного ключа
  •  
  • json-values-iterate — запускає зазначені команди для кожного ключа
  •  
  • json-iterate — запускає зазначені команди для кожного елемента
  •  
 
 Складнощі
Зрозуміло, такими методами неможливо вирішити проблему обробки довільного json'а — він може виявитися занадто «неструктурованим». Але по-перше input'и роблять таки передбачуваний вид json'а, а по-друге, обробка json'а таки більш передбачувана, ніж обробка «типу тут пробілами елементи розділяються» в існуючому Шеллі.
 
 Реалізація
Я б сам написав, але частина потрібного я не знаю, на щось мені не вистачає часу. Не програміст, я. Таємною думкою статті є, що «хтось напише за мене», але якщо такого не знайдеться, то залишиться хоча б програмна стаття з мотивацією довчити (ся) і зробити самому.
 
Якщо хтось готовий за подібне взятися — буду вкрай вдячний. Якщо ні, буду свій фіговий пітон расчехлять — і ідеї та пропозиції вітаються.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.