Hlavní navigace

VisiData – švýcarský nožík pro prohlížení a konverzi dat

Pavel Tišnovský

VisiData je velmi užitečný program určený pro prohlížení a konverzi mnoha typů datových souborů, včetně formátů CSV, XLS, JSONu, XML, ale i databázových souborů (SQLite…), binárních obrázků apod.

Doba čtení: 26 minut

Sdílet

11. Konverze a export dat

12. Příklady provedené konverze

13. Vykreslování grafů v nástroji VisiData

14. Vykreslení grafu z tabulky s jediným sloupcem s hodnotami

15. Zobrazení grafů s více řadami hodnot

16. Graf typu X-Y

17. Práce s rastrovými obrázky PNG

18. Malý výlet do historie výpočetní techniky – aplikace VisiCalc

19. Odkazy na Internetu

1. VisiData – švýcarský nožík pro prohlížení a konverzi dat

Aplikaci VisiData, s níž se alespoň ve stručnosti seznámíme v dnešním článku, je skutečně možné považovat v oblasti prohlížení, základního zpracování a popř. i v oblasti konverze dat za jakýsi univerzální a v mnoha situacích užitečný švýcarský nožík. VisiData lze v první řadě použít pro prohlížení různých typů souborů, zejména souborů obsahujících data ve formě dvourozměrných tabulek (CSV, TSV, textové soubory s volitelnými oddělovači, XLS), dále souborů s obecně vnořenými datovými strukturami (zde jsou podporovány formáty JSON, XML, YAML) a zapomenout nesmíme ani na možnost prohlížení databázových souborů (například lze přímo otevřít soubory databáze SQLite). Pracovat lze, i když v omezené míře, i s rastrovými obrázky a v případě potřeby je možné si dopsat konvertor pro vlastní datové soubory. Tento program pro svůj běh vyžaduje pouze prakticky jakýkoli emulátor terminálu, a to i přesto, že dokáže (samozřejmě s různými omezeními) zobrazit i grafy s jedním či několika průběhy. Lze ho tedy používat i vzdáleně přes SSH atd. atd.

Obrázek 1: Vestavěná nápověda v aplikaci VisiData je strukturována naprosto stejně, jako klasické manuálové stránky.

Nezávisle na typu souboru obsahujícího zkoumané informace se nástroj VisiData snaží o to, aby se pro zobrazení dat používala stejná metoda připomínající tabulkové procesory (ostatně název VisiData připomíná starodávný tabulkový procesor VisiCalc, který taktéž pracoval v textovém režimu). Díky tomu, že je celý program primárně řízen klávesovými zkratkami, je práce s ním velmi rychlá, ovšem samozřejmě se předpokládá, že si uživatel osvojí alespoň základní příkazy pro ovládání. V případě potřeby je samozřejmě součástí VisiData i vestavěná nápověda.

Poznámka: mnohé příkazy jsou odvozeny od Vi/Vimu, takže uživatelé těchto textových editorů mají určitou výhodu.

Kromě interaktivní práce s aplikací VisiData je ovšem možné provádět i konverze dat, a to přímo z příkazového řádku, bez spuštění celoobrazovkového textového uživatelského rozhraní. I s tímto konceptem se samozřejmě seznámíme v navazujících kapitolách.

Poznámka: vzhledem k tomu, že se VisiData používá mj. i pro interaktivní práci, je možné (a vhodné) si informace z článku doplnit i několika videi, v nichž jsou některé možnosti tohoto nástroje názorně ukázány. Tato videa naleznete na adrese https://www.youtube.com/pla­ylist?list=PLxu7QdBkC7drrAG­fYzatPGVHIpv4Et46W.

Obrázek 2: Prakticky celá aplikace VisiData je naprogramována v Pythonu, takže (pokud nebudeme používat nějaké přídavné moduly) by s její instalací neměl být problém (předpokládá se použití Pythonu 3).

2. Instalace nástroje VisiData

Instalace nástroje VisiData může proběhnout dvěma způsoby. V případě, že je tato aplikace dostupná ve formě balíčku určeného přímo pro vaši distribuci, stačí si tento balíček nainstalovat. Pokud tomu tak není, můžeme využít již výše zmíněného faktu, že VisiData je naprogramován v Pythonu a že je dostupný na PyPi. Pro instalaci v tomto případě použijeme nástroj pip, resp. pip3. Instalaci provedeme pro aktuálně přihlášeného uživatele, takže se program nainstaluje do adresáře ~/.local/, což mj. znamená, že pro instalaci nebudeme potřebovat oprávnění administrátora:

$ pip3 install --user visidata
 
Collecting visidata
  Downloading https://files.pythonhosted.org/packages/a6/f3/e16712dc1d51e59c3e1f925b3375c6774c135ea7f5c39597c976bd2ef991/visidata-1.5.2.tar.gz (123kB)
      100% |████████████████████████████████| 133kB 1.4MB/s
      Requirement already satisfied: python-dateutil in ./.local/lib/python3.6/site-packages (from visidata)
      Requirement already satisfied: six>=1.5 in ./.local/lib/python3.6/site-packages (from python-dateutil->visidata)
      Installing collected packages: visidata
        Running setup.py install for visidata ... done
        Successfully installed visidata-1.5.2
Poznámka: pro instalaci pro všechny uživatele vynechejte přepínač –user a spouštějte správce balíčků s právy administrátora.

Pro plnou podporu práce s rastrovými obrázky uloženými ve formátu PNG však budeme potřebovat nainstalovat ještě další Pythonovskou knihovnu nazvanou Pypng. I tato knihovna, která je mimochodem naprogramována v Pythonu a nezávisí tedy na libpng, je dostupná na PyPi, takže instalaci provedeme naprosto stejným způsobem, jako u předchozího balíčku:

$ pip3 install --user pypng
Collecting pypng
  Downloading https://files.pythonhosted.org/packages/0e/39/993a5feea8ed9c2eebd70c6e7c20cb4b0823588f5ab0afab4b0be95ebc23/pypng-0.0.19.tar.gz (293kB)
      100% |████████████████████████████████| 296kB 1.4MB/s
      Installing collected packages: pypng
        Running setup.py install for pypng ... done
        Successfully installed pypng-0.0.19
Poznámka: podobně jako některé další přídavné moduly je i výše zmíněna knihovna pypng pouze nepovinným doplněním aplikace VisiData. Proto ji musíme instalovat explicitně; nejedná se o povinnou závislost.

Po (doufejme, že úspěšné) instalaci se přesvědčíme, že je aplikace VisiData spustitelná. Pro její spuštění se používá příkaz vd, který by měl být umístěn v adresáři, jenž je součástí obsahu proměnné prostředí PATH (pokud tomu tak není, upravte si tuto proměnnou):

Zjištění, zda se nástroj vd nachází na očekávaném místě v adresářové struktuře:

$ whereis vd
 
vd: /home/tester/.local/bin/vd

Poslední stabilní verze programu VisiData by měla být 1.5.2, což taktéž pro jistotu ověříme:

$ vd --version
 
saul.pw/VisiData v1.5.2
Poznámka: pokud budete potřebovat načítat i tabulky z Microsoft Excelu uložené ve formátu XLSX, nainstalujte si navíc balíček pojmenovaný openpyxl, který samozřejmě opět naleznete na PyPi. Podobně pro práci s tabulkami uloženými v databázi Postgres budete potřebovat balíček psycopg2
.

3. První spuštění aplikace VisiData

V případě, že spustíte příkaz vd bez uvedení dalších přepínačů, zobrazí se jeho celoobrazovkové textové uživatelské rozhraní, do kterého se aplikace VisiData pokusí načíst seznam všech souborů (včetně jejich typu), který bude sestaven i rekurzivně z obsahu všech podadresářů, jenž budou nalezeny. Potenciálně se tedy může jednat o časově poměrně náročnou operaci, zejména pokud máte připojený síťový disk. Na druhou stranu je však tato vlastnost velmi užitečná ve chvíli, kdy máme adresář obsahující velké množství datových souborů, které je zapotřebí prozkoumat a popř. nějakým způsobem zpracovat.

Obrázek 3: Zobrazení seznamu souborů ve formě tabulky (ostatně naprostá většina informací se zobrazuje právě ve formě tabulky).

Ve chvíli, kdy se pokusíte otevřít soubory s koncovkami .zip, .gz, .bz2, popř. .xz, pokusí se nástroj VisiData nejprve rozbalit obsah těchto souborů a následně zobrazit přímo získaná (.gz) data popř. seznam nalezených souborů v archivu (.zip atd.).

4. Načítání a prohlížení dat reprezentovaných dvourozměrnými tabulkami (CSV atd.)

Nyní si již můžeme ukázat některé základní možnosti, které nám nástroj VisiData nabízí. Začneme sice tou nejjednodušší, ale velmi užitečnou vlastností – načítáním a prohlížením dat reprezentovaných dvourozměrnými tabulkami. Tato data bývají typicky uložena v těchto formátech (v žádném případě se nejedná o vyčerpávající výčet):

  • CSV neboli Comma-Separated Values [1] je jedním z nejčastěji používaných souborových formátů v této oblasti, a to přesto, že je export a import CSV v některých případech problematický (například některé české mutace Excelu namísto čárek používají středníky, problémy nastávají s buňkami obsahujícími znaky pro konec řádku atd.). Tyto soubory jsou mnohdy obrovské, ovšem s jejich zobrazením ve VisiData nebývají ani v tomto případě problémy. Pokud máte při importu či exportu potíže se zpracováním CSV, můžete použít několik přepínačů příkazového řádku s přesnou specifikací, jak se má konverze provést.
  • TSV neboli Tab-Separated Values [2] [3] je velmi podobným formátem, ovšem s tím rozdílem, že oddělovačem jednotlivých buněk je znak tabulátoru. Podobně jako v případě CSV i zde existuje několik voleb zadávaných na příkazovém řádku, které ovlivňují způsob importu (zda tabulka obsahuje hlavičky sloupců atd.).
  • Existuje i mnoho aplikací, v nichž jsou tabulková data uložena ve formě běžných textových souborů s nějakými oddělovači odlišnými od výše zmíněného tabulátoru (relativně často se jedná o středníky, dvojtečky nebo o znak |). Buď se jedná o zobecnění formátů CSV a TSV [4], nebo může mít textový soubor podobu naformátovaných sloupců s pevnou délkou (a tedy bez problémů čitelných uživatelem). V tomto případě se VisiData pokusí soubor analyzovat (přesněji řečeno při výchozím nastavení analyzovat prvních 1000 řádků) a na základě toho navrhnout, kde se nachází jednotlivé sloupce. Příkladem takového souboru je například https://www.cnb.cz/cs/finan­cni_trhy/devizovy_trh/kur­zy_devizoveho_trhu/denni_kur­z.txt.

Se všemi výše zmíněnými typy souborů dokáže aplikace VisiData pracovat, i když v některých případech může dojít k určitým problémům (například se mi nepodařilo bez chyb načíst mé daňové přiznání vyexportované z formátu Excelu do CSV :-). Důležité je, že všechny tři skupiny formátů slouží pouze pro přenos surových dat, bez dalších informací o typech sloupců atd. Tyto informace ovšem můžeme interaktivně doplnit po načtení příslušné tabulky do programu VisiData. Podívejme se nyní na několik ukázek:

Obrázek 4: Zobrazení souboru s daty reprezentovanými tabulkou a uloženými ve formátu CSV. Po načtení není zřejmé, jaké jsou typy dat v jednotlivých sloupcích, takže se předpokládá, že se jedná o texty (řetězce). Tomu odpovídá i zarovnání a chybějící příznak v popisu sloupců.

Obrázek 5: Samotné příkazy programu VisiData jsou uloženy ve formátu TSV, takže si je můžeme velmi snadno zobrazit a popř. vhodným způsobem modifikovat.

Obrázek 6: Pokus o načtení textového souboru /etc/passwd, který používá vlastní oddělovače jednotlivých prvků v záznamech. V tomto případě se načetla tabulka s jediným sloupcem.

Obrázek 7: Stejný soubor, ovšem načtený s volbou –delimiter=:. Nyní se sloupce rozpoznaly správně, ovšem VisiData předpokládá, že první řádek obsahuje popisu sloupců. I tato možnost je samozřejmě konfigurovatelná.

5. Pohyb po zobrazené tabulce

Pro pohyb v zobrazených tabulkách je možné použít několik klávesových zkratek, které jsou vypsány v tabulce pod odstavcem:

Klávesová zkratka Význam
šipky pohyb po sloupcích a řádcích naprosto stejným způsobem, jako v tabulkových procesorech
h, l přesun na předchozí/následující sloupec (převzato z Vi/Vimu)
j, k přesun na další/předchozí řádek (opět převzato z Vi/Vimu)
gh, gl přesun na první/poslední sloupec
gj, gk přesun na poslední/první řádek
G přesun na první řádek (převzato z Vi/Vimu)
gg přesun na poslední řádek (opět převzato z Vi/Vimu)

Velmi užitečné jsou i funkce určené pro vyhledávání v datových souborech a pro přeskok kurzoru na nalezenou buňku. Tyto funkce jsou založeny na běžných regulárních výrazech:

Klávesová zkratka Význam
/ vyhledání směrem ke konci tabulky, ovšem jen v aktuálním sloupci
? vyhledání směrem  začátku tabulky, ovšem jen v aktuálním sloupci
g/ jako příkaz /, ovšem pro všechny sloupce
g? jako příkaz ?, ovšem pro všechny sloupce
n přechod na další nalezený řetězec (regulární výraz se znovu nezadává)
N přechod na další nalezený řetězec v opačném směru

Při zadávání regulárních výrazů můžete používat i znaky „^“ a „$“ v případě, že potřebujete najít text na začátku nebo na konci buněk.

Obrázek 8: Začátek vyhledání řetězce „2000“ (řetězec se zapisuje na spodním řádku terminálu).

Obrázek 9: Vyhledání řetězce „2000“ v tabulce.

6. Přidání metainformací o typech sloupců

V předchozích odstavcích jsme si řekli, že zejména u textově orientovaných formátů CSV a TSV nemáme k dispozici žádnou informaci o typech dat, tj. například informaci o tom, že první sloupec obsahuje celá čísla, druhý řetězce, další reálná čísla, čtvrtý data atd. Tyto metainformace je možné po načtení souboru doplnit, a to zcela jednoduchým a především rychlým způsobem – s využitím kurzorových šipek nebo kláves h a l vybereme příslušný sloupec a následně stiskem jedné klávesy určíme typ dat. K dispozici přitom máme tyto klávesové zkratky:

Klávesová zkratka Význam
~ sloupec obsahuje obecné řetězce
# sloupec obsahuje celá čísla
% sloupec obsahuje reálná čísla (resp. přesněji řečeno hodnoty s řádovou tečkou)
$ sloupec obsahuje peněžní částky
@ sloupec obsahuje datum (jak asi předpokládáte, tato volba ne vždy funguje k plné spokojenosti)
z# přepnutí zobrazení: délka dat (ve znacích), nikoli jejich hodnota

Podívejme se na způsob použití těchto zkratek:

Obrázek 10: Tabulka ihned po načtení souboru s tabulárními daty uloženými ve formátu CSV.

Obrázek 11: Změna typu dat prvního sloupce – celá čísla. To, jaký typ dat je ve sloupci uložen, je patrné ze znaku zobrazeného za názvem sloupce (zde #).

Obrázek 12: Změna typu dat druhého sloupce – čísla s řádovou tečkou. Povšimněte si změny zobrazení (zarovnání doprava) i značky v záhlaví sloupce.

7. Základní práce s databázovými soubory

Nyní se dostáváme k velmi zajímavému a potenciálně užitečnému tématu, protože nástroj VisiData dokáže načítat a zobrazit obsah souborů používaných některými typy relačních databází. Především je podporován formát databáze SQLite. Soubory používané touto databází máte pravděpodobně na svém počítači v hojném množství, protože SQLite je používána například Firefoxem či některými správci balíčků.

VisiData dokáže formát rozpoznat na základě jeho obsahu a koncovky. Pokud se to z nějakého důvodu nepodaří, můžete použít přepínač -f sqlite:

$ vd -f sqlite foo_bar_baz.db

Kromě toho je možné přistoupit i k obsahu běžící databáze Postgresu, a to následujícím způsobem (potřebujete přitom výše zmíněný balíček Psycopg2):

$ vd postgres://username:password@hostname:port/database

Základní práce s databázovými soubory je relativně jednoduchá, což je ostatně patrné i při pohledu na následující screenshoty. Ty vznikly prohlížením databáze používané systémem DNF/YUM/RPM:

Obrázek 13: Po otevření databázového souboru se nejdříve zobrazí seznam objektů, které jsou v tomto souboru uloženy. Vidíme, že se kromě tabulek zobrazí i informace o triggerech či o indexech. Ve sloupci SQL je zobrazen příkaz DDL (Data Definition Language), kterým se daný objekt (samozřejmě prázdný) vytvoří.

Obrázek 14: Zobrazení obsahu jedné vybrané tabulky. Jedná se o běžnou tabulku se třemi sloupci. Pro návrat do předchozího pohledu použijte klávesovou zkratku q.

Obrázek 15: Jeden z nejlepších způsobů zobrazení neexistující hodnoty (NULL) v jiné tabulce pocházející ze stejné databáze.

Poznámka: podobným způsobem se pracuje i s Excelovskými sešity, protože sešit se taktéž (obecně) skládá z několika tabulek, z nichž jednu je nutné na začátku vybrat.

8. Načtení souborů se strukturovanými daty (JSON atd.)

Jak jsme si již řekli v úvodním odstavci, dokáže nástroj VisiData pracovat i se strukturovanými daty, které bývají uloženy ve formátech JSON, YAML či XML (částečně i v HTML). S těmito formáty se pracuje prakticky stejným způsobem, takže si tuto funkcionalitu předvedeme na JSONu, konkrétně na metainformacích o javascriptovém balíčku Wisp. Tento soubor má následující obsah:

{
  "name": "wisp",
  "id": "wisp",
  "version": "0.10.0",
  "description": "Homoiconic JS with clojure syntax, s-expressions & macros",
  "author": {
    "name": "Irakli Gozalishvili",
    "email": "rfobic@gmail.com",
    "url": "http:\/\/jeditoolkit.com"
  },
  "homepage": "https:\/\/github.com\/Gozala\/wisp",
  "keywords": [
    "compiler",
    "language",
    "transpiler",
    "javascript",
    "lisp",
    "clojure",
    "maros",
    "s-expression",
    "homoiconicity",
    "functional"
  ],
  "repository": {
    "type": "git",
    "url": "https:\/\/github.com\/Gozala\/wisp.git",
    "web": "https:\/\/github.com\/Gozala\/wisp"
  },
  "bugs": {
    "url": "https:\/\/github.com\/Gozala\/wisp\/issues\/"
  },
  "licenses": [
    {
      "type": "BSD New",
      "url": "http:\/\/opensource.org\/licenses\/BSD-3-Clause"
    }
  ],
  "devDependencies": {
    "browserify": "2.35.2",
    "wisp": "0.9.0-beta2"
  },
  "engines": {
    "node": ">=0.4.0"
  },
  "main": ".\/wisp.js",
  "bin": {
    "wisp": ".\/bin\/wisp.js"
  },
  "scripts": {
    "prepublish": "make all",
    "test": "make all && make test"
  },
  "dependencies": {
    "escodegen": "git:\/\/github.com\/Constellation\/escodegen.git#master",
    "base64-encode": "~1.0.1",
    "commander": ">=2.2.0"
  },
  "_id": "wisp@0.10.0",
  "_shasum": "22ad07beec62b236bb869b2e7990a2c7336c9e01",
  "_from": "wisp@latest",
  "_npmVersion": "1.4.9",
  "_npmUser": {
    "name": "gozala",
    "email": "rfobic@gmail.com"
  },
  "maintainers": [
    {
      "name": "gozala",
      "email": "rfobic@gmail.com"
    }
  ],
  "dist": {
    "shasum": "22ad07beec62b236bb869b2e7990a2c7336c9e01",
    "tarball": "https:\/\/registry.npmjs.org\/wisp\/-\/wisp-0.10.0.tgz"
  },
  "directories": {

  },
  "_resolved": "https:\/\/registry.npmjs.org\/wisp\/-\/wisp-0.10.0.tgz"
}

Povšimněte si, že se jedná o slovník (asociativní pole) obsahující jako prvky buď další slovníky nebo pole. Jak vypadá práce s takovým souborem v aplikaci VisiData, která primárně pracuje s tabulkami:

Obrázek 16: Načtení souboru ve formátu JSON. Vidět můžeme pouze klíče a hodnoty na nejvyšší úrovni v hierarchii objektů. Každá dvojice klíč+hodnota představuje jeden sloupec tabulky.

Obrázek 17: Samozřejmě se můžeme podívat i na obsah jednotlivých hodnot (což jsou mnohdy další objekty popř. pole).

Obrázek 18: V případě, že některá z prohlížených hodnot obsahuje pole, je toto pole zobrazeno jako běžná tabulka (typicky s jediným sloupcem, protože se v JSONu často setkáme právě s jednorozměrnými poli).

9. Rozdělení sloupců na základě regulárního výrazu

Zmínit se musíme i o další užitečné funkci. Jedná se o možnost rozdělení aktivního sloupce, tj. sloupce, na němž se nachází vybraná buňka, na několik nových sloupců, a to na základě uživatelem zadaného regulárního výrazu. Tímto výrazem se specifikuje znak či sekvence znaků použitá pro oddělení jednotlivých částí textu takovým způsobem, aby ho bylo možné rozdělit do několika buněk. Příkaz, který tuto funkci provádí, se spouští klávesovou zkratkou : (dvojtečka). Po zadání dvojtečky se očekává specifikace regulárního výrazu potvrzeného klávesou Enter.

Opět se podívejme na celý postup, který není příliš složitý:

Obrázek 19: Znovu jsme načetli obsah souboru /etc/passwd. VisiData v tomto případě automaticky nerozeznal oddělovače sloupců, ovšem to nevadí, protože v tomto můžeme použít regulární výraz.

Obrázek 20: Zadání regulárního výrazu. V tomto případě je výraz tvořen pouze dvojtečkou, která je pravým oddělovačem. Uživatelem zapsanou dvojtečku jsem pro jistotu zvýraznil světlemodrým obdélníkem.

Obrázek 21: Výsledek rozdělení sloupce na základě zadaného regulárního výrazu.

10. Rozdělení sloupců na základě skupin definovaných v regulárním výrazu

Aktivní sloupec je ovšem možné rozdělit na více sloupců i další užitečnou operací, která se spouští klávesovou zkratkou ; (středník). Po zadání této klávesové zkratky se opět očekává regulární výraz, který však má v tomto okamžiku odlišný význam – neurčuje ty znaky, které slouží k oddělení buněk, ale měl by obsahovat skupiny (podvýrazy v kulatých závorkách), přičemž po akceptaci textu regulárním výrazem se z obsahu každé skupiny stane buňka v novém sloupci (sloupcích).

Podívejme se na praktický příklad; opět přitom využijeme soubor /etc/passwd. Budeme chtít z (jediného) sloupce se všemi hodnotami vytvořit dva nové sloupce, přičemž v prvním sloupci bude pouze login a další sloupec bude obsahovat zbytek řádku, ovšem kromě oddělovače, kterým je dvojtečka. V příslušném regulárním výrazu tedy budou dvě skupiny uzavřené ho kulatých závorek. V první skupině je očekáváno jméno složené ze znaků malé abecedy, druhá skupina může obsahovat libovolné znaky (ovšem nesmí být prázdná):

([a-z]+):(.+)

Postup i výsledek je patrný z dalších dvou screenshotů:

Obrázek 22: Zadání regulárního výrazu se skupinami (spodní řádek terminálu).

Obrázek 23: Výsledkem bude tabulka se dvěma novými sloupci, z nichž první obsahuje část odpovídající ([a-z]+) a druhá zbývající znaky kromě rozdělovací dvojtečky.

11. Konverze a export dat

Nástroj VisiData je možné použít i pro konverzi, kterou je možné provádět přímo na příkazovém řádku. Podporovány jsou přitom následující výstupní formáty:

Formát Význam
csv Comma-separated values, viz předchozí text
tsv Tab-separated values, viz předchozí text
json jeden objekt se všemi řádky
md tabulka kompatibilní s org-mode
htm/html výstup do HTML
png výstup do rastrového formátu PNG (potřebuje již zmíněnou knihovnu pypng)

Konverzi si otestujeme na souboru /etc/passwd, který ovšem poněkud zkrátíme, aby se článek zbytečně nenatahoval:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

12. Příklady provedené konverze

Konverze do formátu CSV:

$ vd --delimiter=: -o passwd.csv -b passwd
 
root,x,0,0,root,/root,/bin/bash
bin,x,1,1,bin,/bin,/sbin/nologin
daemon,x,2,2,daemon,/sbin,/sbin/nologin
adm,x,3,4,adm,/var/adm,/sbin/nologin
lp,x,4,7,lp,/var/spool/lpd,/sbin/nologin
sync,x,5,0,sync,/sbin,/bin/sync
shutdown,x,6,0,shutdown,/sbin,/sbin/shutdown
halt,x,7,0,halt,/sbin,/sbin/halt
mail,x,8,12,mail,/var/spool/mail,/sbin/nologin
operator,x,11,0,operator,/root,/sbin/nologin
games,x,12,100,games,/usr/games,/sbin/nologin
ftp,x,14,50,FTP User,/var/ftp,/sbin/nologin
nobody,x,99,99,Nobody,/,/sbin/nologin
apache,x,48,48,Apache,/usr/share/httpd,/sbin/nologin

Konverze do formátu JSON:

$ vd --delimiter=: -o passwd.json -b passwd
 
[{"/bin/bash": "/sbin/nologin", "/root": "/bin", "0": "1", "root": "bin", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/sbin", "0": "2", "root": "daemon", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/var/adm", "0": "4", "root": "adm", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/var/spool/lpd", "0": "7", "root": "lp", "x": "x"},
 {"/bin/bash": "/bin/sync", "/root": "/sbin", "0": "0", "root": "sync", "x": "x"},
 {"/bin/bash": "/sbin/shutdown", "/root": "/sbin", "0": "0", "root": "shutdown", "x": "x"},
 {"/bin/bash": "/sbin/halt", "/root": "/sbin", "0": "0", "root": "halt", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/var/spool/mail", "0": "12", "root": "mail", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/root", "0": "0", "root": "operator", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/usr/games", "0": "100", "root": "games", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/var/ftp", "0": "50", "root": "FTP User", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/", "0": "99", "root": "Nobody", "x": "x"},
 {"/bin/bash": "/sbin/nologin", "/root": "/usr/share/httpd", "0": "48", "root": "Apache", "x": "x"}]

Konverze do formátu kompatibilního s org-mode:

$ vd --delimiter=: -o passwd.md -b passwd
 
|root                |x                   |0                   |0                   |root                |/root               |/bin/bash           |
|--------------------+--------------------+--------------------+--------------------+--------------------+--------------------+--------------------|
|bin                 |x                   |1                   |1                   |bin                 |/bin                |/sbin/nologin       |
|daemon              |x                   |2                   |2                   |daemon              |/sbin               |/sbin/nologin       |
|adm                 |x                   |3                   |4                   |adm                 |/var/adm            |/sbin/nologin       |
|lp                  |x                   |4                   |7                   |lp                  |/var/spool/lpd      |/sbin/nologin       |
|sync                |x                   |5                   |0                   |sync                |/sbin               |/bin/sync           |
|shutdown            |x                   |6                   |0                   |shutdown            |/sbin               |/sbin/shutdown      |
|halt                |x                   |7                   |0                   |halt                |/sbin               |/sbin/halt          |
|mail                |x                   |8                   |12                  |mail                |/var/spool/mail     |/sbin/nologin       |
|operator            |x                   |11                  |0                   |operator            |/root               |/sbin/nologin       |
|games               |x                   |12                  |100                 |games               |/usr/games          |/sbin/nologin       |
|ftp                 |x                   |14                  |50                  |FTP User            |/var/ftp            |/sbin/nologin       |
|nobody              |x                   |99                  |99                  |Nobody              |/                   |/sbin/nologin       |
|apache              |x                   |48                  |48                  |Apache              |/usr/share/httpd    |/sbin/nologin       |

13. Vykreslování grafů v nástroji VisiData

V programu VisiData nalezneme i možnost zobrazení několika typů grafů. Jelikož se však jedná o aplikaci primárně určenou pro spuštění v terminálu, která nemá (alespoň prozatím) žádnou přímou vazbu na specializované aplikace pro vykreslování grafů (GNUPlot, Matplotlib, …), je i vykreslování grafů omezeno na možnosti, které běžné terminály podporují (možnosti Xtermu vykreslovat vektorovou grafiku s využitím escape sekvencí jsou dnes již prakticky zapomenuty, což je možná škoda). Nicméně se vraťme k vykreslování grafů programem VisiData. Aby bylo možné i na běžném terminálu dosáhnout relativně dobrého „rozlišení“, vykreslují se grafy s využitím Braillova písma, které nalezneme v Unicode, konkrétně na pozicích 0×28000×28ff. Braillovo písmo je totiž složeno z kombinací několika teček umožňujících zvýšit horizontální rozlišení dvakrát a vertikální rozlišení dokonce čtyřikrát – viz též následující obrázek (původní písmo používalo jen uspořádání 2×3 tečky a tudíž 64 symbolů):

Obrázek 24: Braillovo písmo.

A právě fakt, že nástroj VisiData používá pro zobrazení grafů znaky z Braillova písma, vede k nutnosti použít font, který tyto znaky skutečně obsahuje. Pokud tomu tak není, graf se zdánlivě nevykreslí, i když se po výběru myší ukáže, že minimálně barva popředí znaků je změněná. Můžete se pokusit malým patchem dosáhnout toho, aby se namísto znaků z Braillova písma použily například hvězdičky, ale rozlišení bude v naprosté většině případů skutečně nedostačující:

Obrázek 25: Úprava programu VisiData takovým způsobem, aby se namísto znaků Braillova písma použily hvězdičky.

Poznámka: princip vykreslování rastrové grafiky s využitím znaků z Braillova písma není v aplikaci VisiData ani zdaleka ojedinělý. Je totiž inspirován relativně populární knihovnou pojmenovanou Drawille, která byla záhy po svém vzniku portována i pro mnoho dalších platforem a programovacích jazyků – viz též příslušné odkazy na různé implementace, které naleznete na této stránce.

14. Vykreslení grafu z tabulky s jediným sloupcem s hodnotami

V případě, že používáte emulátor terminálu podporující Unicode (což jsou prakticky všechny dnes využívané emulátory, a to včetně Xtermu) a máte k dispozici font s definicemi všech znaků Braillova písma, můžete si vyzkoušet vykreslení jednoduchého grafu. Postup je popsán v následujících odstavcích.

Nejprve v aplikaci VisiData otevřeme vhodný soubor s daty. Pro demonstrační účely jsem použil soubor percent_bachelors_degrees_wo­men_usa.csv, který si můžete stáhnout z adresy https://github.com/matplo­tlib/matplotlib/blob/master/lib/mat­plotlib/mpl-data/sample_data/percent_bache­lors_degrees_women_usa.csv. Otevření tohoto souboru zajistí příkaz:

$ vd

Po zadání tohoto příkazu by se měla zobrazit tabulka ve formátu:

Obrázek 26: Původní tabulka s daty.

Povšimněte si, že VisiData nezná typ jednotlivých sloupců, takže u všech sloupců používá datový typ řetězec/text. To snadno napravíme. První sloupec obsahuje roky, takže se jedná o celá čísla. Vybereme tento sloupec a stlačením klávesy # určíme jeho typ. Současně ještě stlačením klávesy ! určíme, že tento sloupec obsahuje nezávislé hodnoty vynášené na horizontální osu grafu. Po stisku ! by se měl sloupec zvýraznit odlišnou barvou.

Podobně budeme postupovat i u dalších sloupců, které ovšem obsahují reálné hodnoty, resp. přesněji řečeno procenta studujících daný obor. Stlačením klávesy % na každém z těchto sloupců určíme, že se skutečně jedná o reálná čísla, což je signalizováno mj. i změnou zobrazení (zarovnání doprava atd.)

Pokud budeme chtít některé sloupce odstranit, postačuje po jejich výběru stisknout klávesu -.

Obrázek 27: Příprava pro vykreslení grafu.

Jakmile je výběr proveden, je systém VisiData připraven k zobrazení grafu. To provedeme stiskem klávesy . (tečka). Graf, který se vykreslí, bude obsahovat hodnoty z toho sloupce, který byl při stisku tečky právě vybrán.

Obrázek 28: Výsledný graf.

K předchozímu pohledu se dostaneme stejným příkazem, který již známe – klávesou q.

15. Zobrazení grafů s více řadami hodnot

K dispozici je však i složitější typ grafu, v němž je možné zobrazit více průběhů. Tento graf se vykreslí s využitím příkazu g.. V tomto případě nezáleží na tom, který sloupec byl právě vybrán, protože se zobrazí sloupce všechny:

Obrázek 29: Graf s několika průběhy.

V tomto typu grafu lze (ve chvíli, kdy je zobrazen) použít klávesy 0 až 9 ke skrytí, popř. ke zpětnému zobrazení určitého průběhu, tj. dal ze sloupce 1 až 10.

16. Graf typu X-Y

Ve skutečnosti však systém VisiData podporuje i složitější typ grafu. Jedná se o graf se dvěma nezávislými veličinami a třetí veličinou závislou. V tabulkových procesorech se většinou tento typ grafu označuje jménem X-Y chart či jen X-Y. Aby bylo možné tento graf použít, budete potřebovat tabulku s minimálně třemi sloupci, přičemž hodnoty ze dvou sloupců budou použity pro určení souřadnice bodu v rovině a třetí sloupec pro určení hodnoty (množina hodnot se rozdělí do osmi kategorií, protože k dispozici je pouze osm barev při vykreslování). Sloupce, které mají určovat x-ovou a y-ovou souřadnici, je nutné označit klávesovou zkratkou !; pokud takto označíte jen jeden sloupec, bude pochopitelně vykreslen graf s jedinou nezávislou proměnnou, tj. graf popsaný v předchozí kapitole.

17. Práce s rastrovými obrázky PNG

Tento typ grafu můžeme použít pro zobrazení – i když ve velmi primitivní podobě – rastrových obrázků ve formátu PNG. Pokud totiž takový obrázek do aplikace VisiData načteme, bude reprezentován formou tabulky, v níž každý řádek odpovídá jedinému pixelu. První sloupec bude obsahovat x-ovou souřadnici pixelu, druhý y-ovou souřadnici a další sloupce pak hodnoty jednotlivých barvových složek, průhlednost popř. celý barvový atribut. Dokonce se automaticky vyplní typy všech sloupců a první dva sloupce se označí příznakem nezávislé veličiny. Nám již tedy postačuje vybrat libovolný další sloupec a stiskem klávesy . si zobrazit hodnoty příslušné barvové složky.

Obrázek 30: Tabulka získaná po načtení rastrového obrázku ve formátu PNG.

Obrázek 31: Výsledný „obrázek“ získaný grafem typu X-Y.

18. Malý výlet do historie výpočetní techniky – aplikace VisiCalc

Na závěr se jen ve stručnosti zmiňme o možném původu názvu VisiData. Ten totiž připomíná tabulkový procesor VisiCalc. Jednalo se o první interaktivní aplikaci typu „tabulkový procesor“ (spreadsheet), která v době svého vzniku bezesporu patřila mezi takzvané „killer app“, tj. mezi programy, jenž samy o sobě některé uživatele přesvědčily k tomu, aby si pořídili osobní mikropočítač (a to se bavíme o začátku osmdesátých let minulého století, kdy byly mikropočítače velmi drahé) [1]. VisiCalc byl portován na mnoho typů mikropočítačů, mj. i na slavné počítače Apple II, na počítače kompatibilní s IBM PC atd. Oproti jiným nástrojům určeným pro zpracování dat měl VisiCalc obrovskou výhodu – byl interaktivní a používal paradigma, kterému mnoho uživatelů velmi dobře rozumělo (data byla uložena v dvourozměrných tabulkách, ovšem bez nutnosti přesné specifikace jejich struktury, navíc bylo umožněno jednotlivé buňky adresovat).

Jen pro představu: i na kdysi malém IT trhu se prodalo přes 700000 kopií VisiCalcu, nepočítaje v to samozřejmě pirátské kopie.

Obrázek 32: Tabulkový procesor VisiCalc spuštěný v DOSu (resp. přesněji řečeno v jeho emulátoru).

VisiCalc byl natolik úspěšný, že jeho vydavatel, společnost Personal Software později přejmenovaná na VisiCorp, měla z prodeje VisiCalcu na svoji dobu takřka neuvěřitelné zisky, které se snažila použít pro vývoj dalších softwarových produktů. Jednalo se například o program VisiPlot (kreslení grafů) nebo o relativně jednoduchý textový procesor VisiWord. V roce 1981 se vývojáři VisiCorpu zamýšleli nad tím, jak zlepšit interoperabilitu svých jednotlivých produktů, což by mohlo ve svém důsledku zvýšit jejich oblibu a tím pádem i prodejnost. Došli k tomu, že by bylo vhodné provést tři poměrně zásadní změny: vytvořit jednotné datové struktury, aby spolu programy mohly jednoduše komunikovat (dříve se data musela například exportovat z VisiCalcu a následně importovat do VisiPlotu), umožnit rychlejší přepínání mezi jednotlivými programy bez nutnosti jeden program ukončit a nastartovat druhý a taktéž sjednotit ovládání programů takovým způsobem, aby se uživatelé nemuseli učit rozdílné klávesové zkratky, jiné názvy položek v menu atd.

Obrázek 33: Slavný tabulkový kalkulátor Lotus 1–2–3 s charakteristickým řádkovým menu.

Vzhledem k tomu, že DOS byl a vlastně dodnes je jednoúlohový a jednouživatelský systém, rozhodlo se vedení společnosti VisiCorp vytvořit vlastní plnohodnotný operační systém s GUI nazvaný Visi On, který měl být dokončen v létě roku 1983, tedy například ještě předtím, než byl představen Macintosh.

Obrázek 34: Úvodní (textová – jak jinak :-) obrazovka programu Lotus 1–2–3.

Později byl tabulkový procesor VisiCalc překonán programy, které nabízely lepší uživatelské prostředí, popř. více funkcí či větší výkonnost. Mezi tyto aplikace patřilo především QuattroPro a taktéž slavný Lotus 1–2–3. Ten byl mj. naprogramován v assembleru, právě s ohledem na co největší výkonnosti při zpracování rozsáhlých tabulek (paradoxní možná je, že i první verze VisiCalcu byla naprogramována v assembleru, konkrétně assembleru osmibitových mikroprocesorů MOS 6502)

19. Odkazy na Internetu

  1. VisiData
    http://visidata.org/
  2. VisiData na GitHubu
    https://github.com/saulpw/visidata
  3. Balíček visidata 1.5.2 na PyPi
    https://pypi.org/project/visidata/
  4. Balíček pypng 0.0.19 na PyPi
    https://pypi.org/project/pypng/
  5. An Introduction to VisiData
    https://jsvine.github.io/intro-to-visidata/
  6. VisiData Lightning Demo at PyCascades 2018
    https://www.youtube.com/wat­ch?v=N1CBDTgGtOU&t=134
  7. User Documentation
    https://visidata.org/docs/
  8. Pixel graphics in terminal with unicode braille characters
    https://github.com/asciimoo/drawille
  9. Drawing graphs
    https://visidata.org/docs/graph/
  10. Videa o aplikaci VisiData
    https://www.youtube.com/pla­ylist?list=PLxu7QdBkC7drrAG­fYzatPGVHIpv4Et46W
  11. Manuálová stránka aplikace VisiData
    https://visidata.org/man/
  12. Comma-separated values
    https://en.wikipedia.org/wiki/Comma-separated_values
  13. Tab-separated values
    https://en.wikipedia.org/wiki/Tab-separated_values
  14. Tab Separated Values (TSV): a format for tabular data exchange
    http://jkorpela.fi/TSV.html
  15. Delimiter-separated values
    https://en.wikipedia.org/wi­ki/Delimiter-separated_values
  16. Integrovaná vývojová prostředí ve Fedoře: vykreslování grafů s využitím knihoven Numpy a matplotlib
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-vykreslovani-grafu-s-vyuzitim-knihoven-numpy-a-matplotlib/
  17. Integrovaná vývojová prostředí ve Fedoře: vykreslování grafů s využitím knihoven Numpy a matplotlib (2.část)
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-vykreslovani-grafu-s-vyuzitim-knihoven-numpy-a-matplotlib-2-cast/
  18. Integrovaná vývojová prostředí ve Fedoře: vykreslování grafů s využitím knihoven Numpy a matplotlib (dokončení)
    https://mojefedora.cz/integrovana-vyvojova-prostredi-ve-fedore-vykreslovani-grafu-s-vyuzitim-knihoven-numpy-a-matplotlib-dokonceni/
  19. Openpyxl na PyPi
    https://pypi.org/project/openpyxl/
  20. Psycopg2 na PyPi
    https://pypi.org/project/psycopg2/
  21. Xterm
    https://invisible-island.net/xterm/manpage/xterm.html
  22. xterm: Tektronix 4014 Emulator
    http://physics.oregonstate­.edu/~landaur/nacphy/coping-with-unix/node140.html
  23. Visi On (Wikipedia)
    http://en.wikipedia.org/wiki/Visi_On
  24. VisiCorp's VisiOn Graphical User Interface System for IBM and compatible PCs
    http://www.digibarn.com/co­llections/software/VisiOn/in­dex.html
  25. Obrazem: Operační systémy od roku 1981
    http://digitalne.centrum.cz/obrazem-operacni-systemy-od-roku-1981/diskuze/undefined/un­defined/?pid=6150
  26. VisiCorp Visi On
    http://toastytech.com/guis/vi­sion.html
  27. A Guided Tour of Visi On
    http://www.guidebookgalle­ry.org/articles/aguidedtou­rofvision
  28. VisiCalc Executable for the IBM PC
    http://www.bricklin.com/his­tory/vcexecutable.htm