abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 04:00 | Komunita

S ukončením podpory Windows 7 spustila Nadace pro svobodný software (FSF) kampaň Upcycle Windows 7 s peticí žádající Microsoft, aby zveřejnil zdrojové kódy tohoto již nepodporovaného operačního systému pod svobodnou licencí. S uvedením Windows 7 v roce 2009 byla spuštěna kampaň Windows 7 Sins.

Ladislav Hagara | Komentářů: 17
dnes 03:00 | Komunita

Sedmý ročník největší české konference o redakčním systému WordPress WordCamp Praha 2020 se uskuteční v sobotu 29. února v pražském Cubex Centru na Pankráci. Na účastníky letos čekají tři tracky přednášek českých i zahraničních řečníků, několik workshopů, případových studií a samozřejmě i Happiness bar, kam se můžete přijít poradit s odborníky. Je to také ideální příležitost potkat stovky dalších WordPress nadšenců i profesionálů.

… více »
smíťa | Komentářů: 0
dnes 02:00 | IT novinky

Společnost Proton Technologies stojící za virtuální privátní sítí ProtonVPN otevřela všechny aplikace ProtonVPN pod licenci GPLv3. Současně oznámila, že tyto aplikace prošly bezpečnostním auditem. Také díky spolupráci s organizací Mozilla.

Fair | Komentářů: 0
včera 04:00 | Komunita

Na Youtube byl zveřejněn videozáznam jednání odvolacího soudu ve sporu Grsecurity (Open Source Security) vs. Bruce Perens [reddit].

Ladislav Hagara | Komentářů: 5
včera 03:00 | Komunita

Byl vyhlášen vítězný wallpaper soutěže o nejlepší wallpaper pro KDE Plasmu LTS 5.18. Vítězným a tedy výchozím wallpaperem je Volna. Autor wallpaperu Nikita Babin získává notebook od TUXEDO Computers.

Ladislav Hagara | Komentářů: 12
včera 02:00 | Nová verze

Nová verze ODF 1.3 (Open Document Format), výchozího formátu dokumentů LibreOffice, byla schválena standardizační komisí OASIS. Mezi novinky ve formátu patří digitální podpis a XML šifrování dokumentů založené na OpenPGP, plus několik vylepšení funkcí již dostupných v ODF 1.2, jako jsou nové typy regresních křivek pro grafy, nová specifikace počtu desetinných míst ve formátování čísel, speciální styl záhlaví/zápatí pro první

… více »
Zdeněk Crhonek | Komentářů: 0
24.1. 09:00 | Komunita

V Brně na FIT VUT probíhá DevConf.CZ 2020, již dvanáctý ročník jedné z největších akcí zaměřených na Linux a open source ve střední Evropě. Na programu je celá řada zajímavých přednášek a workshopů. Aktuální dění lze sledovat například na Twitteru.

Ladislav Hagara | Komentářů: 0
23.1. 23:44 | Komunita

Společnost Psyonix, v květnu 2019 koupena společností Epic Games, oznámila konec podpory počítačové hry Rocket League na Linuxu a macOS. Poslední aktualizace pro tyto operační systémy vyjde v březnu a odstraní možnost hrát tento automobilový fotbal online.

Ladislav Hagara | Komentářů: 13
23.1. 14:33 | Zajímavý článek

Nová čísla časopisů od nakladatelství Raspberry Pi: MagPi 89 (pdf), HackSpace 26 (pdf) a 27 (pdf) a Wireframe 28 (pdf), 29 (pdf) a 30 (pdf).

Ladislav Hagara | Komentářů: 0
23.1. 14:11 | Nová verze

Byla vydána nová verze 12.7 open source alternativy GitHubu, tj. softwarového nástroje s webovým rozhraním umožňujícího spolupráci na zdrojových kódech, GitLab (Wikipedie). Představení nových vlastností v příspěvku na blogu.

Ladislav Hagara | Komentářů: 3
Zdají se vám sny s IT tématikou?
 (9%)
 (1%)
 (13%)
 (17%)
 (54%)
 (7%)
Celkem 270 hlasů
 Komentářů: 10, poslední 18.1. 16:18
Rozcestník

Používáme AWK pro filtrování XML

28.12.2019 19:40 | Přečteno: 1727× | Softwarové inženýrství | poslední úprava: 28.12.2019 19:49

Příkaz AWK slouží pro zpracování textu a typicky se pomocí něj filtrují a transformují jednoduché formáty, kde jsou řádky pomocí nějakých oddělovačů rozdělené na políčka. Takže můžeme udělat např.

cat /etc/fstab | awk '/^[^#]/ {print $2}'

a vypsat si druhý „sloupeček“ obsahující název adresáře, kam se připojuje příslušný oddíl. AWK je jeden z klasických unixových nástrojů. Ty fungují docela hezky, pokud je formát dat hodně jednoduchý a nemáme v něm žádné záludnosti jako víceřádkový text, nebo znak oddělovače uvnitř hodnoty atd. Toto ale velká část dat nesplňuje a nějaké ty záludnosti v nich jsou. Pak můžeme buď předstírat, že formát je jednoduchý a mít nespolehlivý software/skript (doufat, že okrajové případy nenastanou) nebo se pustíme do programování a začneme používat nějaké knihovny nebo psát parsery. Většinou to znamená opustit staré známé nástroje a začít to dělat úplně jinak. V dnešním příkladu si ukážeme, že si můžeme nechat klasický nástroj a jazyk AWK a zpracovávat pomocí něj i složitější formáty.

Dejme tomu, že máme nějaká strukturovaná data jako /etc/dbus-1/system.d/org.freedesktop.NetworkManager.conf, která obsahují politiky (oprávnění) pro D-Bus služby:

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
	<policy user="root">
		<allow own="org.freedesktop.NetworkManager"/>
		<allow send_destination="org.freedesktop.NetworkManager"/>

		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.PPP"/>

		<allow send_interface="org.freedesktop.NetworkManager.SecretAgent"/>
		<!-- These are there because some broken policies do
		   <deny send_interface="..." /> (see dbus-daemon(8) for details).
		   This seems to override that for the known VPN plugins.
		-->
		<allow send_destination="org.freedesktop.NetworkManager.openconnect"/>
		<allow send_destination="org.freedesktop.NetworkManager.openswan"/>
		<allow send_destination="org.freedesktop.NetworkManager.openvpn"/>
		<allow send_destination="org.freedesktop.NetworkManager.pptp"/>
		<allow send_destination="org.freedesktop.NetworkManager.vpnc"/>
		<allow send_destination="org.freedesktop.NetworkManager.ssh"/>
		<allow send_destination="org.freedesktop.NetworkManager.iodine"/>
		<allow send_destination="org.freedesktop.NetworkManager.l2tp"/>
		<allow send_destination="org.freedesktop.NetworkManager.libreswan"/>
		<allow send_destination="org.freedesktop.NetworkManager.fortisslvpn"/>
		<allow send_destination="org.freedesktop.NetworkManager.strongswan"/>
		<allow send_interface="org.freedesktop.NetworkManager.VPN.Plugin"/>

		<allow send_destination="org.fedoraproject.FirewallD1"/>

		<!-- Allow the custom name for the dnsmasq instance spawned by NM
			from the dns dnsmasq plugin to own it's dbus name, and for
			messages to be sent to it.
		-->
		<allow own="org.freedesktop.NetworkManager.dnsmasq"/>
		<allow send_destination="org.freedesktop.NetworkManager.dnsmasq"/>
	</policy>
	<policy user="whoopsie">
		<allow send_destination="org.freedesktop.NetworkManager"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.DBus.Introspectable"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.DBus.Properties"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Connection.Active"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device"/>
	</policy>
	<policy context="default">
		<deny own="org.freedesktop.NetworkManager"/>

		<deny send_destination="org.freedesktop.NetworkManager"/>

		<!-- Basic D-Bus API stuff -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.DBus.Introspectable"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.DBus.Properties"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.DBus.ObjectManager"/>

		<!-- Devices (read-only properties, no methods) -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Adsl"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Bond"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Bridge"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Bluetooth"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Wired"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Generic"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Gre"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Infiniband"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Macvlan"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Modem"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.OlpcMesh"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Team"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Tun"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Veth"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Vlan"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.WiMax.Nsp"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.AccessPoint"/>

		<!-- Devices (read-only, no security required) -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.WiMax"/>

		<!-- Devices (read/write, secured with PolicyKit) -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device.Wireless"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Device"/>

		<!-- Core stuff (read-only properties, no methods) -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Connection.Active"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.DHCP4Config"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.DHCP6Config"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.IP4Config"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.IP6Config"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.VPN.Connection"/>

		<!-- Core stuff (read/write, secured with PolicyKit) -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Settings"/>
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.Settings.Connection"/>

		<!-- Agents; secured with PolicyKit.  Any process can talk to
		the AgentManager API, but only NetworkManager can talk
		to the agents themselves. -->
		<allow send_destination="org.freedesktop.NetworkManager"
			   send_interface="org.freedesktop.NetworkManager.AgentManager"/>

		<!-- Root-only functions -->
		<deny send_destination="org.freedesktop.NetworkManager"
			  send_interface="org.freedesktop.NetworkManager"
			  send_member="SetLogging"/>
		<deny send_destination="org.freedesktop.NetworkManager"
			  send_interface="org.freedesktop.NetworkManager"
			  send_member="Sleep"/>
		<deny send_destination="org.freedesktop.NetworkManager"
			  send_interface="org.freedesktop.NetworkManager.Settings"
			  send_member="LoadConnections"/>
		<deny send_destination="org.freedesktop.NetworkManager"
			  send_interface="org.freedesktop.NetworkManager.Settings"
			  send_member="ReloadConnections"/>

		<deny own="org.freedesktop.NetworkManager.dnsmasq"/>
		<deny send_destination="org.freedesktop.NetworkManager.dnsmasq"/>
	</policy>

	<limit name="max_replies_per_connection">1024</limit>
	<limit name="max_match_rules_per_connection">2048</limit>
</busconfig>

A hledáme v nich pravidla, která něco povolují běžným uživatelům (kdokoli jiný než root). To znamená, že chceme provést dotaz, který je složený ze dvou podmínek spojených AND operátorem. V pseudokódu tedy něco jako:

pravidlo == "allow" AND uživatel != "root"

Pokud známe AWK, tak i víme, jak v něm tento pseudokód konkrétně zapsat:

($1 == "allow" && $2 != "root")

nebo pokud dostaneme hodnoty do patřičných proměnných, tak:

(policy == "allow" && user != "root")

Takže máme skoro hotovo, implementovali jsme kód dle zadání, jen jaksi nemáme nad čím a kde tento kód spustit. A tady nám pomohou Relační roury, které umožní převést data z různých formátů na jednotný relační tvar a pak nad nimi provádět různé transformace (už bez ohledu na to, v jakém formátu data původně byla), a nakonec data převést na nějaký výstupní formát.

Řešení potom může vypadat takto:

#!/bin/bash

getXML() {
	# Just read a file:
	cat "/etc/dbus-1/system.d/org.freedesktop.NetworkManager.conf"
	# Or we can wget or curl it from the network
	# or generate on-the-fly using some other command.
}

parseXML() {
	# Convert the XML tree structure into multiple relations.
	# Use XPath expressions to find record nodes
	# and to find attributes inside them.
	relpipe-in-xmltable \
		--relation 'policy' \
			--records '/busconfig/policy/allow|/busconfig/policy/deny' \
			--attribute 'policy'           string 'name()' \
			--attribute 'user'             string '../@user' \
			--attribute 'context'          string '../@context' \
			--attribute 'own'              string '@own' \
			--attribute 'send_destination' string '@send_destination' \
			--attribute 'send_interface'   string '@send_interface' \
			--attribute 'send_member'      string '@send_member' \
		--relation 'limit' \
			--records '/busconfig/limit' \
			--attribute 'name'             string '@name' \
			--attribute 'value'            integer '.'
}

filterRecords() {
	# Use native AWK command (called from relpipe-tr-awk)
	# with all its power to filter the records.
	# Work with named fields instead of numbered columns.
	relpipe-tr-awk \
		--relation "policy" \
		--where 'policy == "allow" && user != "root"'

	# Of course, we can do the same using SQL:
	# relpipe-tr-sql \
	#	--relation "policy" \
	#		"SELECT * FROM policy WHERE policy = 'allow' AND user <> 'root'"
	#	--copy 'limit'

	# Or using Guile (Scheme):
	# relpipe-tr-guile \
	#	--relation policy \
	#	--where '(and (string= $policy "allow") (not (string= $user "root")) )'
}

formatOutput() {
	relpipe-out-tabular
	# Or generate some other format:
	# relpipe-out-ods       # spreadsheet for e.g. LibreOffice
	# relpipe-out-xml       # XML e.g. for further XSLT or XQuery processing
	# relpipe-out-recfile   # recfile for further GNU Recutils processing
	# relpipe-out-asn1      # ASN.1 BER for the telco guys
	# relpipe-out-gui       # display data in a GUI window
	# etc.
}

# put the whole pipeline together:
getXML | parseXML | filterRecords | formatOutput

Tenhle shellový skript nám vygeneruje následující výstup:

policy:
 ╭─────────────────┬───────────────┬──────────────────┬──────────────┬────────────────────────────────┬────────────────────────────────────────────────────┬──────────────────────╮
 │ policy (string) │ user (string) │ context (string) │ own (string) │ send_destination      (string) │ send_interface                            (string) │ send_member (string) │
 ├─────────────────┼───────────────┼──────────────────┼──────────────┼────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────┤
 │ allow           │ whoopsie      │                  │              │ org.freedesktop.NetworkManager │                                                    │                      │
 │ allow           │ whoopsie      │                  │              │ org.freedesktop.NetworkManager │ org.freedesktop.DBus.Introspectable                │                      │
 │ allow           │ whoopsie      │                  │              │ org.freedesktop.NetworkManager │ org.freedesktop.DBus.Properties                    │                      │
 │ allow           │ whoopsie      │                  │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager                     │                      │
 │ allow           │ whoopsie      │                  │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Connection.Active   │                      │
 │ allow           │ whoopsie      │                  │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device              │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.DBus.Introspectable                │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.DBus.Properties                    │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.DBus.ObjectManager                 │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Adsl         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Bond         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Bridge       │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Bluetooth    │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Wired        │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Generic      │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Gre          │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Infiniband   │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Macvlan      │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Modem        │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.OlpcMesh     │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Team         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Tun          │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Veth         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Vlan         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.WiMax.Nsp           │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.AccessPoint         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.WiMax        │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device.Wireless     │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Device              │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Connection.Active   │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.DHCP4Config         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.DHCP6Config         │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.IP4Config           │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.IP6Config           │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.VPN.Connection      │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager                     │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Settings            │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.Settings.Connection │                      │
 │ allow           │               │ default          │              │ org.freedesktop.NetworkManager │ org.freedesktop.NetworkManager.AgentManager        │                      │
 ╰─────────────────┴───────────────┴──────────────────┴──────────────┴────────────────────────────────┴────────────────────────────────────────────────────┴──────────────────────╯
Record count: 39
limit:
 ╭────────────────────────────────┬─────────────────╮
 │ name                  (string) │ value (integer) │
 ├────────────────────────────────┼─────────────────┤
 │ max_replies_per_connection     │            1024 │
 │ max_match_rules_per_connection │            2048 │
 ╰────────────────────────────────┴─────────────────╯
Record count: 2

Díky převodu na jednotný relační tvar jsme mohli použít svůj oblíbený jazyk AWK – a stejně tak bychom mohli použít i jazyky SQL nebo Guile (Scheme), podle toho, co nám vyhovuje. Případně bychom mohli data filtrovat a zpracovat ve stylu klasických nástrojů grep, cutsed, ovšem s možností zpracovávat komplexní data obsahující víceřádkové hodnoty nebo různé záludné znaky (aniž by se nám třeba záznamy a atributy slily omylem do jednoho nebo se náhodně rozdělily).

Všimněme si, že ze zdrojového XML jsme vygenerovali dvě relace: policylimit. Jednu z nich (limit) jsme nechali rourou projít bezezměny, zatímco druhou (policy) jsme filtrovali pomocí AWK a vybrali z ní jen ty záznamy, které nás zajímají.

Výstupním formátem nemusí být jen tabulka v terminálu, ale může to být třeba ODS sešit pro LibreOffice, XML, ASN.1 BER, CSV, Recfile atd. Nebo můžeme pro každý záznam spustit příkaz (něco jako xargs) či si data zobrazit v GUI okně (třeba i s grafy, pokud to pro dané hodnoty dává smysl – zrovna v tomto příkladě to moc smysl nedává, ale jinde to může být docela užitečné).

Originál v angličtině: AWKing through a XML file

       

Hodnocení: 100 %

        špatnédobré        

Anketa

Jaký jazyk je vám nejbližší pro jednoduché filtrování?
 (30 %)
 (60 %)
 (10 %)
Celkem 10 hlasů

Obrázky

Používáme AWK pro filtrování XML, obrázek 1 Používáme AWK pro filtrování XML, obrázek 2 Používáme AWK pro filtrování XML, obrázek 3

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

28.12.2019 19:52 max
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
uš jsem se radoval z čistého unixového přístupu a on tam stejně nase*e ty svoje hovnopajpy
28.12.2019 20:04 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Pekne, az na to, ze cemu rikas relacni tvar a relace, je ve skutecnosti tabulka, pricemz (z definice) ne vse, co je tabulka je i relace.
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
xkucf03 avatar 28.12.2019 20:38 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Je to asi jako kdyby sis stěžoval, že silniční kolo není silniční, protože se s ním dá jezdit i po poli.

Nebo taky někdy v mceditu upravuji binární soubory (a kupodivu to i funguje). Budeš kvůli tomu tvrdit, že mcedit není textový editor?

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
29.12.2019 11:13 luky
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Nebo taky někdy v mceditu upravuji binární soubory (a kupodivu to i funguje). Budeš kvůli tomu tvrdit, že mcedit není textový editor?

A jakej je v linuxu rozdil mezi textovym a binarnim souborem?
xkucf03 avatar 30.12.2019 09:54 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Z hlediska OS nebo souborového systému v tom rozdíl není. Ty soubory se liší obsahem – textový soubor by měl obsahovat pouze platné posloupnosti bajtů v daném kódování (např. UTF-8). Textový editor běžně předpokládá, že v něm budeš editovat textové soubory, takže pokud v něm otevřeš binární soubor s náhodnými bajty, výsledkem může být chyba (editor odmítne soubor otevřít nebo uložit) nebo ztráta či poškození dat. Ale někdy se textovým editorem podaří upravit i binární soubor, aniž by k poškození došlo (povede se ti přepsat jen ty bajty, které jsi přepsat chtěl).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
29.12.2019 23:06 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Obe ty prirovnani kulhaji.
Nebo taky někdy v mceditu upravuji binární soubory (a kupodivu to i funguje). Budeš kvůli tomu tvrdit, že mcedit není textový editor?
On editor musi byt jen textovy?

man mcedit: mcedit - Internal file editor of GNU Midnight Commander.
Je to asi jako kdyby sis stěžoval, že silniční kolo není silniční, protože se s ním dá jezdit i po poli.
Ono silnicni kolo z definice musi jezdit jen po silnici?

Mne porad nejde do hlavy, proc se v tom projektu za kazdou cenu ohanis temi relacemi, kdyz to relace nejsou a ani nijak nevyuzivas jejich vlastnosti.
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
xkucf03 avatar 30.12.2019 09:48 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Obe ty prirovnani kulhaji. … On editor musi byt jen textovy? … Ono silnicni kolo z definice musi jezdit jen po silnici?

Kolo primárně určené pro jízdu po silnici se nazývá silniční, přestože s ním někdo může jezdit i mimo silnici.

Editor určený primárně k úpravám textu se nazývá textový, přestože s ním někdo může editovat i binární soubory.

Formát nebo nástroj primárně určený k práci s relačními daty se nazývá relační, přestože ho někdo může použít i pro nerelační data.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
29.12.2019 23:30 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jeste doplnim.
Je to asi jako kdyby sis stěžoval, že silniční kolo není silniční, protože se s ním dá jezdit i po poli.
Kdyz budes mluvit o silnicim kole a budes tim myslet libovolne kolo (protoze prece vsechno jezdi po silnici), tak ti (v lepsim pripade) lidi nebudou spravne rozumet, (v horsim) te budou mit za ignoranta, co to nerozumi.

Vsimni si, ze silnici kolo je specialni pripad (obecneho) kola, stejne jako na relaci lze nahlizet jako na specialni pripad (obecne) tabulky.

Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
28.12.2019 23:05 .
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Fajn, ty tvoje relpipes jsou fakt šikovný, ale to jak dementně je tlačíš, je fakt ... dementní.
xkucf03 avatar 28.12.2019 23:12 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

V blogu o nich píši poprvé (nepřímo se toho týkaly i zápisky z 9. 6. 2018 a 21. 7. 2017). A zpráviček o tom za rok vyšlo šest, což je v průměru jedna za dva měsíce. Je to moc?

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
28.12.2019 23:18  
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
O šest víc než by se slušelo.
29.12.2019 18:38 .
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
+1
29.12.2019 09:17 _
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Klidně pritlač. Na blogu, kde Golis sere jeden nečitelný zápisek o hovne za druhým, má každý rozumný anglický nebo český zápisek cenu zlata.

2.1. 12:43 drnest | skóre: 9
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Já to neberu, že to tlačí. Něco zajímavého naprogramoval a aby to jen neleželo někde ladem, tak o tom musíš říct lidem. Udělat pár přikladů jak se to dá použít. Napsat o tom někde, kde se to lidi dozví.
7.1. 15:40 OldFrog {Ondra Nemecek} | skóre: 32 | blog: Žabákův notes | Praha
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
+1 Přece je fajn vědět, kdo se čemu věnuje, ne?
-- OldFrog
29.12.2019 09:22 _
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

V anketě chybí Python

xkucf03 avatar 29.12.2019 09:42 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Dal jsem tam to, co je reálně použitelné. Modul relpipe-tr-python sice existuje, ale je hodně nezralý. Je potřeba vymyslet, jak by se tam měl ten výraz zapisovat a jak mapovat proměnné.

K tomu zápisu výrazu: v AWK je to takto:

--relation "policy" \
--where 'policy == "allow" && user != "root"'

v SQL:

--relation "policy" \
"SELECT * FROM policy WHERE policy = 'allow' AND user <> 'root'"

a v Guile:

--relation policy \
--where '(and (string= $policy "allow") (not (string= $user "root")) )'

Kromě toho lze dělat i transformace (volba --for-each). Chci to předělat, aby to v Pythonu bylo podobně, jako v těch ostatních jazycích.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Bedňa avatar 29.12.2019 11:08 Bedňa | skóre: 34 | blog: Žumpa | Horňany
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Toto nebolo nikdy treba, pretože všetko bolo v prehľadných textových súboroch. Ďakujeme RedHat, že nám z Linux Enviroment spravil nečitateľné XML hell.
KERNEL ULTRAS video channel >>>
Heron avatar 29.12.2019 12:39 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Já ti furt nevím. Na jednu stranu je super, co jsi ukázal v tom skriptu, že lze v každém kroku použit rozmanité množství možností (tři filtry, 6 výstupů) bez jakékoliv změny jinde, na druhou stranu nějak pořád nevidím ten správný "sweet spot", kde by to mělo uplatnění. Všechny ty příklady mi zatím přijdou dost umělé a šly by vyřešit mnohem jednodušeji jinak.

Navíc v nadpisu je AWK a XML, ale AWK se tady používá dost uměle a až po té, co mu to XML jiný program předžvýká a navíc to ani nestojí na AWK a je možno použít dvě další filtrovací alternativy. AWK se XML ani nedotkne.

Chápu, že cílem příkladu bylo ukázat modulárnost toho filtrovacího nástroje, na druhou stranu kdyby ten filter se o to filtrování postaral zcela ve vlastní režii (například systém predikátů / testů jak má find), tak by si na awk nikdo ani nevzpomněl.

Ale těžko říct, možná to má někdo jinak. Já, pokud už kombinatorikou grepu, sedu v terminálu nedokážu vyfiltrovat to co chci, tak okamžitě přejdu na vyšší jazyk (před 10 lety java, dneska python, za dva roky možná golang) a napíšu si to v něm. A pokud se mi nechce se pachtit s vlastními pravidly, tak to třeba hodím do sqlite a udělám nad tím potřebný select, výsledky proženu třeba regexp a je to. Pokud to má být pravidelně používaný nástroj, tak se to uhladí, ale tím se to ještě více vzdaluje od bashe.

Jaký jazyk je vám nejbližší pro jednoduché filtrování?
Z nabízených možností jen SQL a to hlavně pokud jsou potřeba joiny, groupy a agregační funkce; pokud se jedná o případ, kde by nad jednou tabulkou byl jen jednoduchý logický výraz (WHERE user == 'pepa' AND event='login') tak bych SQL ani nepoužil a filtroval si to rovnou pomocí prostředků daného jazyka (bud naivně jako if neco, nebo pomocí map, filter nástrojů).
xkucf03 avatar 29.12.2019 14:42 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Chápu, že cílem příkladu bylo ukázat modulárnost toho filtrovacího nástroje, na druhou stranu kdyby ten filter se o to filtrování postaral zcela ve vlastní režii (například systém predikátů / testů jak má find), tak by si na awk nikdo ani nevzpomněl.

Zrovna na filtrování XML je ideální XQuery, což je vlastně takové SQL pro stromové struktury (a nakonec to jde použít i pro ne-XML data a ne-XML výstupy). Případně by šlo to filtrování udělat už na úrovni XPath dotazů v rámci toho relpipe-in-xmltable.

Nicméně u těch relačních rour je pointa v tom, že se ty kroky (vstup, transformace, výstup) rozdělí a můžeš je libovolně skládat a řetězit. A pak používáš jazyk, který ti je nejbližší (AWK, SQL, Scheme, regulární výrazy…) bez ohledu na to, odkud ta data přišla. Zároveň pořád zůstáváš v shellu a pracuješ s proudem bajtů, který můžeš kdykoli nasměrovat do souboru nebo poslat po síti a jinde/jindy to odtamtud zase načíst.

Co se týče efektivity, dalo by se to optimalizovat tak, že se na tu rouru nebudeš dívat jako na kód v Bashi, ale jako na nějakou vlastní gramatiku, která je jeho podmnožinou, a celé to pak buď interpretovat v rámci jednoho procesu nebo dokonce zkompilovat do jedné binárky. Dalo by se tam hezky využít GraalVM a mít tam líné vyhodnocování, díky kterému by se nepočítala/nenačítala data, se kterými se později už nepracuje (zatímco v té současné implementaci s klasickými rourami jednotlivé kroky neví, co následuje po nich a je potřeba načíst všechna data, i když se pak třeba v dalším kroku zahodí). Ale to je poměrně vzdálená budoucnost – nejdřív je potřeba dotáhnout tu specifikaci a vydat v1.0.

A pokud se mi nechce se pachtit s vlastními pravidly, tak to třeba hodím do sqlite a udělám nad tím potřebný select

To v relpipe-tr-sql1 můžeš udělat taky – jsou tam volby --file--file-keep a data ti pak zůstanou ve standardním .sqlite souboru nebo se odtamtud načtou. Smysl to může mít kvůli těm vstupním a výstupním filtrům pro různé formáty, které už jsou hotové a nemusíš je psát, a kvůli parametrizovaným dotazům, díky kterým lze bezpečně předat data zvenku a nehrozí SQL injection.

V příští verzi v0.15 to ještě nebude, ale ve v0.16 chystám podporu libovolných RDBMS, ne jen SQLite.

Z nabízených možností jen SQL a to hlavně pokud jsou potřeba joiny, groupy a agregační funkce; pokud se jedná o případ, kde by nad jednou tabulkou byl jen jednoduchý logický výraz (WHERE user == 'pepa' AND event='login') tak bych SQL ani nepoužil a filtroval si to rovnou pomocí prostředků daného jazyka (bud naivně jako if neco, nebo pomocí map, filter nástrojů).

Mám to podobně, SQL je mi hodně blízké, nebo na ta stromová data se mi líbí XQuery. Samozřejmě, že lze psát i if, map atd. v libovolném jazyce, to je normální programování, ale často se mi nic programovat nechce, chci jen ad-hoc něco vyřešit, a pak se mi líbí, když to můžu udělat na jednom řádku v shellu, mám tam bash completion a z terminálového okna a Bashe se vlastně stává IDE, mám tam napovídání a můžu to ladit tím, že si data v určitém kroku nasměruji do souboru nebo tam rouru přeruším a dám tam relpipe-out-tabular a podívám se, co tam je za data. Dá se to distribuovat i na víc počítačů a část té roury přes SSH pouštět jinde. Což tedy není nic revolučního, je to klasický unixový shell se vším, na co jsme zvyklí, jen s drobným vylepšením, kterým je ten datový formát umožňující spolehlivě předávat strukturovaná data nebo i více sad různých dat v jednom proudu. Ostatně jedna z hlavních myšlenek je nevymýšlet nic moc nového, napsat minimum kódu a jen poskládat dohromady ty osvědčené fungující věci.

Mimochodem, předcházel tomu prototyp SQL-API (a taky trochu alt2xml) z roku 2014 – v těch prezentacích jsem vysvětloval tu motivaci za tím (i když nevím, jestli je to z těch slajdů bez přednášky úplně pochopitelné). Ty myšlenky by se měly postupně objevit v implementaci Relačních rour (např. pohled na systémové procesy, uživatele, disky atd. formou relací, nad kterými lze pak provádět SQL dotazy, nebo AWK, Scheme, Python, dle vkusu každého… zatím je implementovaný jen pohled na fstab/mtab jako ukázka). A zároveň to musí zůstat minimalistické a modulární (ty moduly mají běžně nižší stovky řádků, což je ve srovnání s jinými projekty nic – a to je tam ještě dost prostoru pro refaktoring a čištění, takže v budoucnu by ta komplexita měla ještě trochu klesnout). Taky je tam nějaká konvergence s SQL-DK… a už dneska můžeš přes SQL-DK vytahat data z libovolné DB a poslat je do relační roury. Hodí se to např. pro offline/lokální dotazy, kdy si přeliješ nějakou podmnožinu dat třeba ze vzdáleného PostgreSQL do lokální SQLite databáze, a pak si s těmi daty hraješ, aniž bys potřeboval server, ale máš stále k dispozici SQL (a navíc i jiné dotazovací/transformační jazyky).

[1] existuje i symlink/režim relpipe-in-sql, který má na vstupu SQL skript s CREATE TABLE, INSERT… – takže jde psát SELECTy nad DDL/DML skriptem: cat skript.sql | relpipe-in-sql …

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 29.12.2019 15:34 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Plánuješ k tomu udělat i persistentní storage, nebo jen využiješ toho, že jedna komponenta to může načítat z různých zdrojů? Proč se ptám, nedávno jsem dělal inventuru všech svých projektů a přechod z GitLabu na Gitea (zejména z důvodu toho, že Gitlab je strašný moloch a na FreeBSD bych to musel instalovat a udržovat po komponentách) a všiml jsem si, že všechny moje projekty jsou storage-centrické. Což není až takové překvapení, ale překvapilo mě, jak moc. Takže nejdřív navrhnu způsob ukládání a až potom kolem toho postavím funkce. Takže historicky úložiště jako BerkeleyDB, CDB, TDB apod projekty, pochopitelně PostgreSQL jako univerzální úložiště všeho (zejména souborů). Základem je prostě storage téměř libovolného typu a až potom nad tím dělám funkcionalitu, která alespoň z počátku víc připomíná nástroj pro admina, než cokoliv jiného (dump, load, check, convert apod.). Ale z nějakého důvodu je pro mě ta persistence základ. Ono se to taky snadno paralelizuje, když vše naházím do jednoho storage, tak si workery mohu spustit na libovolném počtu strojů na síti, každý si ze storage vezme jeden objekt a zpět ho tam uloží. Takto vznikl můj poslední toy project, když jsem potřeboval zpracovat asi 600tis balíků dat a zjistil jsem, že žádný rozumný jednoduchý síťový job manager neexistuje a všechno jsou obří projekty pro cern apod. Tak jsem si napsal atomickou síťovou frontu jobů, na všech strojích na síti pustil tolik workerů, kolik to má jader a celkový čas tak urychlil asi tak 8x.
xkucf03 avatar 29.12.2019 16:39 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Plánuješ k tomu udělat i persistentní storage

Ne, viz:

What Relational pipes are not?

Database system, DBMS – we focus on the stream processing rather than data storage. Although sometimes it makes sense to redirect data to a file and continue with the processing later.

Je to v první řadě datový formát pro předávání strukturovaných dat (relací) ve formě proudu bajtů. Kdo ten proud bude generovat a kdo ho bude číst, to už je na tobě. Ano, jsou k tomu i nástroje, ale primární je ten formát. Takže svým způsobem ano – v centru jsou data a až kolem nich vznikají nějaké nástroje. Ale tato data neleží na jedné hromadě, nýbrž tečou odněkud někam.

Persistenci si uděláš tak, jak potřebuješ – můžeš to jednoduše přesměrovat do souboru (ten ale není nijak indexovaný), nebo skrze relpipe-tr-sql uložit do .sqlite souboru, ten už indexovaný bude, nebo to můžeš (v přespříští verzi) poslat třeba do PostgreSQL databáze. Nebo to proženeš skrz XML/Recfile/CSV/ODS nebo jiný filtr, který to převede na textový formát, a budeš to verzovat v Mercurialu, Gitu atd. a můžeš si pak hezky porovnávat, co se v kterých verzích změnilo a jaká je historie jednotlivých záznamů (což by třeba u toho SQLite nešlo a musel by sis historii implementovat sám v rámci SQL) nebo to jednoduše distribuovat posíti pomocí push/pull příkazů příslušného DVCS.

Pokud je pro tebe centrální bod relační databáze, tak ti Relační roury můžou posloužit jako vstupně/výstupní filtr pro různé formáty případně jako řádkový SQL klient. Pak je ale spousta lidí, kteří relační databáze (včetně takové SQLite) považují za příliš komplexní software a snaží se mu vyhýbat – a pro ně zase dává smysl si ta data ukládat třeba v některém z těch textových formátů. Někdo zase nemá rád XML – tak ho nemusí používat, prostě ten XML modul bude ignorovat, nebude ho ani stahovat a použije nějaké jiné moduly. Někdo zase nesnáší polskou notaci, tak místo Guile modulu použije AWK. Každý si z toho může vzít to, co mu vyhovuje – a zároveň můžou mezi sebou komunikovat společným jazykem (datovým formátem).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 29.12.2019 18:32 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Pokud je pro tebe centrální bod relační databáze
To ani ne, pro mě je centrální bod libovolné úložiště splňující určitá kritéria. Používal jsem hromadu jednoduchých knihoven, viz ty BerkleyDB, trivial db apod. Snadno použitelné key-value storage, ještě před tím, než to bylo cool a hype. To, že se dlouhodobě ukazuje, že PostgreSQL je pro mě nejlepší univerzální úložiště, ještě neznamená, že nutně potřebuju relační databázi. Vlastnosti vycházející z relační algebry nejsou pro mě až tak důležité, jako třeba ACID (zejména teda atomicita a persistence). PostgreSQL předběhl v rychlosti třeba i dokumentovou MongoDB, což je pikantní, protože tyto db vznikaly právě proto, že SQL je "pomalé a k ničemu". Nakonec je PostgreSQL i jednou s nejrychlejších nosql db.

Ale to jsem odbočil. Pro mě jsou zkrátka primární data a až potom k nim vymýšlím funkce. Data se snažím rozdělovat tak, aby šla jednoduše nezávisle na sobě zpracovat. Ty máš primární přenosný datový formát a k tomu proudové funkce. Jasně, obojí je možné i když asi na různá použití. Jen mě přišlo jako dobrý nápad k těm proudům poskytovat i storage. Ale to tam máš / budeš mít, ale jinak a modulárně. Jasně, proč ne.
Josef Kufner avatar 29.12.2019 18:53 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jak tak na to koukám, oba máte stejný přístup a mluvíte o tomtéž.

Jediný rozdíl je, že jeden má data umístěna staticky a persistentně, kdežto druhý má data umístěna v proudu a jen dočasně.
Hello world ! Segmentation fault (core dumped)
29.12.2019 23:11 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Vlastnosti vycházející z relační algebry nejsou pro mě až tak důležité, jako třeba ACID (zejména teda atomicita a persistence)
Kdyz uz rypu do xkucf, tak ACID opravdu nevychazi z vlastnosti relacni algebry. Jsou to ortogonalni (silne zadouci) koncepty, napr. jsou KV-uloziste, ktere (ne)jsou ACID, a jsou RDBMS, ktere (ne)jsou ACID.
Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
30.12.2019 14:52 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Já ti furt nevím. Na jednu stranu je super, co jsi ukázal v tom skriptu, že lze v každém kroku použit rozmanité množství možností (tři filtry, 6 výstupů) bez jakékoliv změny jinde, na druhou stranu nějak pořád nevidím ten správný "sweet spot", kde by to mělo uplatnění. Všechny ty příklady mi zatím přijdou dost umělé a šly by vyřešit mnohem jednodušeji jinak.
+1

Tady je to napraseno v Py:

#!/usr/bin/python3

import sys
import xml.etree.ElementTree as ET

tree = ET.parse(sys.stdin)
pols = [pol for pol in tree.getroot().iter('policy') if pol.get('user') != 'root']
rules = [{
        'name': pol.attrib.get('user', '[{}]'.format(pol.attrib.get('context'))),
        'send_destination': rule.attrib.get('send_destination'),
        'send_interface': rule.attrib.get('send_interface'),
    } for pol in pols for rule in pol.iter('allow')]

for rule in rules:
    print('{name:<20} {send_destination} {send_interface}'.format(**rule))

.. a to nejsem moc dobrej Py programátor, takže Skutečné™ Py programátory prosím o shovívavost a případnou opravu.

Dá se k tomu říct, že to není "správné" protože to je naprasené, nicméně ve výsledku u těch relpipes mi to přijde naprasné ještě hůř - je to výřečné, má to svou vlastní specielní syntaxi, je na to potřeba nainstalovat desítky balíčků a výsledek je tabulka, která se blbě zobrazuje na webu (protože fonty)...

Přitom ten nápad filtrovat data SQL-like dotazováním v zásadě není špatná. Proč to ale raději nenapsat jako LINQ-like rozšíření do nějakého zavedeného ekosystému jako třeba ten Py nebo JS?
Digitalizace starých listin je přesun informací z šanonu do shannonu.
Heron avatar 30.12.2019 16:02 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
a výsledek je tabulka, která se blbě zobrazuje na webu (protože fonty)...
Tak výsledek si můžeš hodit do čeho chceš.

Já v Pythonu používám Tabulate.

S konverzí na web jsem neměl problém. Používám aha, který umí vzít výstup na terminál i včetně barev a udělat z toho html.
30.12.2019 16:32 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Díky, to je oboje velmi pěkné.
Digitalizace starých listin je přesun informací z šanonu do shannonu.
xkucf03 avatar 30.12.2019 16:19 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Příloha:

A jsi schopný ten Python kód napsat z hlavy a bez dokumentace? Protože ty Relační roury z hlavy nebo maximálně s bash completion psát jde.

Mimochodem, ten tvůj skript se nečte zrovna nejlíp, když některé části je potřeba číst od konce (přemýšlím, kde se bere proměnná rule a pak koukám, že někde za tím je for pol in pols for rule in … a jinde je zase klasický for cyklus, kde deklarace proměnných předchází jejich použití).

A znovu připomínám, že cílem není až tak nástroj, jako spíš datový formát, který půjde používat napříč různými nástroji a jazyky a propojí je dohromady. Jinak je celkem nesporné, že když se člověk omezí na jeden programovací jazyk, dá se vymyslet i něco elegantnějšího. Klidně by to mohl být framework v Javě1, kde budeš nějak šikovně řetězit metody, používat lambdy atd.

je to výřečné

To je schválně. Viz Use --long-options. Psaní ti ušetří bash completion a při čtení ti to pomůže, protože celé slovo ti řekne víc než nějaká kryptická jednopísmenková zkratka.

je na to potřeba nainstalovat desítky balíčků

Důležitější metrika mi přijde počet řádků kódu. V podstatě všechny podobné projekty mají řádově vyšší komplexitu a navíc nejsou modulární, takže si z nich nemůžeš vybrat jen to, co tě zajímá, a musíš to vzít jako celek i se všemi závislostmi.

výsledek je tabulka, která se blbě zobrazuje na webu (protože fonty)...

Nemáš to spíš nějaké rozbité u sebe? Koukal jsem na to teď ve čtyřech prohlížečích a ve všech se to zobrazuje správně. Viz příloha.

Nicméně výstup relpipe-out-tabular je určený primárně pro terminál (taky je to obarvené pomocí ANSI sekvencí). Jasně, dá se vložit (tím se ty ANSI sekvence oříznou) do e-mailu, na web, nebo kamkoli, kde lze použít neproporcionální písmo. Ale zrovna na web by se hodila víc HTML tabulka – tzn. použít relpipe-out-xml a prohnat to triviální XSLT šablonou, která ti to nastyluje přesně, jak potřebuješ.

Přitom ten nápad filtrovat data SQL-like dotazováním v zásadě není špatná.

Taky si myslím. Ale pro někoho je (jakékoli) SQL (nebo srovnatelná technologie) přehnaně komplexní a někdy i takové SQLite je příliš těžkotonážní. Jindy zase potřebuješ pracovat s XML, relačními databázemi atd. A ten společný formát je způsob, jak tyhle světy s diametrálně odlišnou mírou komplexity propojit.

Generovat data v tomhle formátu je triviální, tudíž to můžeš dělat i v programu, do kterého si nic komplexního zatahovat nechceš. Ale konzumovat tato data už pak může kdokoli, jakýmkoli nástrojem – někdo si je může filtrovat jen pomocí regulárních výrazů, někdo pomocí SQL, někdo v Guile nebo AWKu… to ale toho, kdo ta data generuje, nemusí zajímat a nijak ho to neomezuje. Případně můžeš generovat CSV, XML nebo Recfile – to se do té relační roury dá taky dobře zapojit. Spoustě programům bohužel dodnes chybí výstup ve strojově čitelném formátu. A spousta programů řeší vlastním kódem, jak „hezky“ naformátovat data v konsoli. Přitom by bylo daleko lepší na výstup poslat data ve strojově čitelném formátu a vizualizaci nechat už na někom jiném – prostě klasické: dělat jednu věc a dělat ji pořádně. Před lety jsem např. narazil na chybu v inotify-tools v generování CSV, které tam někdo nasmolil v Céčku. Přitom by stačilo, kdyby ten nástroj posílal na výstup hodnoty oddělené nulovým bajtem – a ty by sis to načetl a zpracovat třeba ve for cyklu v Bashi nebo nějakým jiným nástrojem.

Proč to ale raději nenapsat jako LINQ-like rozšíření do nějakého zavedeného ekosystému jako třeba ten Py nebo JS?

Takových nástrojů v různých jazycích existuje už dost, ne? Kromě toho, že normálně programuji, mám hodně rád i unixové roury a myšlenku psaní jednoduchých skriptů ve kterých pospojuješ různé nástroje dohromady. A v podstatě jediná věc, která mi tam chybí a která mne štve, je absence standardního formátu pro popis strukturovaných dat. Hrozně dlouho se omílalo, jak je bezva, že jsou to textové proudy a předstíralo se, že pomocí nich lze předávat data, aniž by formát byl nějak specifikovaný… ale to je omyl nebo z nouze ctnost. Funguje to jen u triviálních případů a to víceméně náhodou. Pro spolehlivější fungování potřebuješ aspoň CSV (RFC 4180), ve kterém se ti aspoň hodnoty nebudou náhodně slívat a rozpadat ve chvíli, kdy se v nich objeví nějaký „nečekaný“ znak. Ale pořád je to málo, protože s CSV přeneseš v jednom proudu jen jednu relaci (či tabulku) a chybí ti tam záhlaví (nerozlišíš ho od prvního řádku hodnot) a datové typy… Taky ta averze k binárním formátům je historický omyl vycházející z negativních emocí a dávné neblahé zkušenosti s nějakými proprietárními formáty. Bohužel si spousta lidí vypěstovala asociaci binární-proprietární – což jsou ale ve skutečnosti ortogonální kategorie.

Ta absence strukturovaných formátů/rozhraní se řešila i pod Bystroušákovými blogy o objektovém OS. Objektový přístup by se mi taky líbil, ale je to výrazně složitější na implementaci. Oproti tomu ty relace jsou jednodušší, omezenější a dají se implementovat snadno jen drobným vylepšením stávajících OS a programů (resp. OS ani shelly kvůli tomu ani není potřeba upravovat, použijí se tak, jak jsou, a stačí rozšířit jednotlivé programy tak, aby uměly generovat a číst strukturovaná data).

[1] i když tam už něco na ten způsob existuje – Apache Camel

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
30.12.2019 18:14 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
A jsi schopný ten Python kód napsat z hlavy a bez dokumentace? Protože ty Relační roury z hlavy nebo maximálně s bash completion psát jde.
Úplně bez dokumentace nejsem schopný psát ani jedno. A pokud ti jde o napovídání, na to je IDE.
A v podstatě jediná věc, která mi tam chybí a která mne štve, je absence standardního formátu pro popis strukturovaných dat.
Důvod, proč takový formát neexistuje je velmi jednoduchý - viz xkcd #927.
Ale pro někoho je (jakékoli) SQL (nebo srovnatelná technologie) přehnaně komplexní a někdy i takové SQLite je příliš těžkotonážní. Jindy zase potřebuješ pracovat s XML, relačními databázemi atd. A ten společný formát je způsob, jak tyhle světy s diametrálně odlišnou mírou komplexity propojit.
Tomu moc nerozumim, vzhledem k tomu, že ani XML ani SQL na ten formát moc nepasuje... Třeba u toho XML musíš, jestli tomu dobře rozumim, ručně nadefinovat transformaci XML na tabulky...
Objektový přístup by se mi taky líbil, ale je to výrazně složitější na implementaci.
Nerozumim použití pojmu 'objektový přístup' v kontextu serializačního formátu, leda bys chtěl serializovat s daty i kód.
Digitalizace starých listin je přesun informací z šanonu do shannonu.
30.12.2019 18:29 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Nemáš to spíš nějaké rozbité u sebe? Koukal jsem na to teď ve čtyřech prohlížečích a ve všech se to zobrazuje správně. Viz příloha.
Je to rozbitý v Chromiu, nevim proč, ale vzpomínám si, že to tu psal i někdo jinej než já...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
xkucf03 avatar 30.12.2019 18:56 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Je to rozbitý v Chromiu

Pak tedy nechápu, proč píšeš:

výsledek je tabulka, která se blbě zobrazuje na webu (protože fonty)...

Používám tam standardní Box-drawing character z Unicodu a jestli se v nějaké kombinaci prohlížeče/písma zobrazují špatně, tak by to chtělo nahlásit spíš u toho prohlížeče nebo u distribuce, než si stěžovat tady (navíc stylem, kdy to prezentuješ jako chybu těch Relačních rour).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
30.12.2019 19:04 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Ok, chyba relpipes to není. Nicméně proč nepoužíváš pro výstup na web HTML tabulku? Ta monospace tabulka je stejně taková nic moc v tom, že se neadaptuje na šířku okna, takže na displej laptopu se mi ani nevejde...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
Martin Tůma avatar 30.12.2019 23:40 Martin Tůma | skóre: 38 | blog: RTFM | Praha
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Je to rozbitý v Chromiu, nevim proč, ale vzpomínám si, že to tu psal i někdo jinej než já...
psal
Každý má právo na můj názor!
30.12.2019 23:45 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
V ábíčkovským CSS to není, mně se to zobrazuje blbě i na Frantovo stránkách a v plaintext souboru (v Chromiu)...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
xkucf03 avatar 31.12.2019 00:01 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Jaké máš v tom Chromiu nastavené písmo? Já jsem si teď schválně pustil Chromium s čistým profilem:

chromium-browser --user-data-dir=xxxx

což zjevně zafungovalo, protože nevidím záložky a další svoje nastavení. A ty tabulky se mi zobrazují v pořádku. Když kouknu do nastavení, tak tam je:

Písmo s pevnou šířkou: Monospace
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 01:12 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Písmo s pevnou šířkou: Monospace
To je jen obecný font selektor, z toho se moc nedozvíš. Když chceš vědět, jakej font je reálně v tom použitej, tak je potřeba otevřít danej html node v devtools a podívat se do Computed styles úplně dolů, kde jsou vypsaný použitý fonty.

Když z toho pre tagu vyhodim ty tabulky, tak mi to píše Droid Sans Mono. Když je tam vrátim, tak k němu přibude ještě Liberation Serif. Usuzuju z toho, že problém je v tom, že Droid Sans Mono je default monospace font, ale neobsahuje některý ty box drawing znaky, a tak ten engine doplní znaky z jinýho fontu, kterej není monospace nebo má jinej rozměr.
Digitalizace starých listin je přesun informací z šanonu do shannonu.
xkucf03 avatar 31.12.2019 01:22 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Příloha:

U mě to vypadá takhle. Nicméně vzhledem k tomu, že ti to zlobí i na Ábíčku a asi i kdekoli jinde (?), tak s tím těžko něco udělám a přijde mi to jako chyba Chromia nebo jeho konfigurace.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 10:31 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
a přijde mi to jako chyba Chromia nebo jeho konfigurace.
Není to chyba Chromia, je to chyba toho konkrétního fontu. Když si nastavim DejaVu Sans Mono, tak je to v pořádku. Ale ve chvíli, kdy ten font ten znak nemá, jako třeba ten Droid Sans Mono, tak to Chromium lépe vyřešit prostě nemůže - i kdyby chytřeji našlo třeba jinej monospace font, ze kterýho by vzalo ty chybějící znaky, tak to obecně nepomůže, protože jinej monospace font může mít jinou šířku znaku, a tudíž by to stejně bylo rozbitý.

To prostě nemá dobrý řešení. S tou tabulkou zkrátka spoléháš na to, že použitý font ty znaky má, což obecně bohužel nemusí vždy platit...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
xkucf03 avatar 31.12.2019 11:43 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Není to chyba Chromia, je to chyba toho konkrétního fontu.

A kdo rozhoduje o tom, jaké písmo Chromium použije? Distribuce? Desktopové prostředí? Chromium? Podle mého je chyba použít jako výchozí písmo takové, které tyto základní znaky neobsahuje. Hlavně, že jsou všude samé pošahané obskurní emoji, ale klasické rámečky, které se používaly už v počítačovém pravěku, nebudou?

je to chyba toho konkrétního fontu.

Že někdo vytvoří písmo, ve kterém takové znaky chybí – budiž. Ale chyba podle mého je, když někdo takové písmo nastaví jako výchozí.

To prostě nemá dobrý řešení. S tou tabulkou zkrátka spoléháš na to, že použitý font ty znaky má, což obecně bohužel nemusí vždy platit...

Ano. A když píši s diakritikou, tak čekám, že čtenář bude mít taky nastavené písmo, které ty české znaky obsahuje. To bychom taky mohli psát všechno v ASCII, pro jistotu. Ale protože máme rok 2019 (2020) a Box-drawing characters jsou globálně používané (není to nějaké lokální specifikum, jako třeba české háčky a čárky), tak mi přijde normální se jim nevyhýbat.

Na vlastních webech můžu přibalit .woff písmo, u kterého budu mít vyzkoušené, že tam ty znaky jsou. Ale tohle moc rád nemám – dávám přednost tomu, když autor webu jen řekne, co má být neproporcionálním nebo jiným písmem… a konkrétní font si nastaví uživatel dle svých potřeb a vkusu. Chápu, že je to v rozporu s moderním pojetím webu, kde je snaha, aby web vypadal na všech počítačů stejně a grafik to měl vše pod kontrolou. Ale mně se líbí spíš ten klasický přístup, kdy web má primárně obsah, zatímco o formě (spolu)rozhodne uživatel a jeho prohlížeč.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 13:42 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
ale klasické rámečky, které se používaly už v počítačovém pravěku
Tyhle rámečky se ale nepoužívaly už v počítačovém pravěku. Způsob, jakým terminál kreslí rámečky, jsem ti tady už posledně psal. S unicode box-drawing znakama to nemá vůbec nic společného. Jestli relpipes tohle kreslí do terminálu, tak to je docela rarita.
Ale chyba podle mého je, když někdo takové písmo nastaví jako výchozí.
vs
a konkrétní font si nastaví uživatel dle svých potřeb a vkusu
Ok, takže uživatel si může nastavit písmo jaké chce, ale musí to spávné, které obsahuje ty znaky, které potřebuješ...

Já nevim, odkud se u mě vzalo to nastavení toho písma jako výchozího, možná jsem si to nastavil sám někdy v minulosti, protože se mi líbilo. Fakt si to nepamatuju. Zatím jsem se na webu kromě relational pipes s použitím box-drawing znaků nesetkal.
Digitalizace starých listin je přesun informací z šanonu do shannonu.
xkucf03 avatar 31.12.2019 14:31 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Způsob, jakým terminál kreslí rámečky, jsem ti tady už posledně psal.

Vím, že jsi to psal. Ale když se podívám na výstup třeba mc (což je asi nejpoužívanější aplikace tohoto typu) pomocí hd, tee nebo strace, tak tam žádnou magii (že by mc říkal terminálu, odkud kam má kreslit přímku) nevidím – najdu tam znaky jako e2 94 80, což je BOX DRAWINGS LIGHT HORIZONTAL' (U+2500) ─ a tytéž bajty generuji i v tom relpipe-out-tabular. Viz příloha a strace -ttf -o mc.strace -s 4096 -xx mc. Ty bajty se normálně zapisují na FD 1.

Ok, takže uživatel si může nastavit písmo jaké chce, ale musí to spávné, které obsahuje ty znaky, které potřebuješ...

V době kdy se běžně do Unicodu a písem cpou různé skládané emoji znaky typu růžový poník s duhovým pérem a zeleným kloboukem na hlavě, tak bych čekal, že tak základní věc jako textové rámečky tam budou taky. Ale možná toho chci moc :-)

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
xkucf03 avatar 31.12.2019 14:35 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Příloha:
Příloha
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 15:06 Vantomas | skóre: 29 | Praha
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Možná bude třeba zohlednit, že "mc" umí více formátů zobrazení, než jen ten "modrý". Když mc spustím přes sériovou linku (vt100), tak je celý v barvách terminálu a rámečky jsou vykreslovány pomocí | a -.
31.12.2019 15:09 Vantomas | skóre: 29 | Praha
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Otevřel jsem si manuál k mc a pokud se to spustí "mc -ab", tak takhle to vidím přes ty sériový terminály.
Josef Kufner avatar 31.12.2019 15:45 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Viz man termcap a terminfo.
Hello world ! Segmentation fault (core dumped)
31.12.2019 22:46 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Vím, že jsi to psal. Ale když se podívám na výstup třeba mc (což je asi nejpoužívanější aplikace tohoto typu) pomocí hd, tee nebo strace, tak tam žádnou magii (že by mc říkal terminálu, odkud kam má kreslit přímku) nevidím – najdu tam znaky jako e2 94 80, což je BOX DRAWINGS LIGHT HORIZONTAL' (U+2500)
Máš pravdu, mc používá Unicode. Ale třeba weechat to dělá tím tradičním způsobem. (Můžeš si to zkusit tak, že když v Konsole nastavíš non-Unicode kódování, tak v mc se to rozbije, zatímco ve weechatu ne.)

Ono v terminálu ten Unicode až tak nevadí, protože emulátor to buď umí interpretovat a vykreslit po svém (konsole, iirc), nebo to minimálně nevadí, protože tam je vždy dodržena ta mřížka.
V době kdy se běžně do Unicodu a písem cpou různé skládané emoji znaky typu růžový poník s duhovým pérem a zeleným kloboukem na hlavě, tak bych čekal, že tak základní věc jako textové rámečky tam budou taky. Ale možná toho chci moc :-)
No však emojis mi taky často nefungujou.
Digitalizace starých listin je přesun informací z šanonu do shannonu.
31.12.2019 23:01 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Rámečky mc by měly fungovat i v non utf8 terminálu - co vím, tak používá ncurses, a ty pro rámečky používají sekundární sadu znaků http://www.melvilletheatre.com/articles/ncurses-extended-characters/index.html. Nicméně musí být správně nastavená proměnná LANG, aby ncurses vygenerovalo escape sekvence. Jak je to pak v ncurses, to jsem nikdy nesledoval - nicméně stopro rámečky fungují i s latin2, latin1.

Naopak např. psql generuje unicode rámečky skrz unicode. Tam by to s latin2 nezafungovalo
xkucf03 avatar 31.12.2019 23:23 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Pravda. Když spustím:

LANG=cs_CZ.ISO-8859-2 strace -ttf -o mc.strace -s 4096 -xx mc

tak to rozbije háčky a čárky, ale rámečky jsou v pořádku. A v logu už ty Unicode rámečky, které tam byly, nejsou.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
1.1. 01:06 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Pokud to používá ty vt-100 rámečky, tak tam někde nejspíš bude "\e(0", "\e)0", "\e*0" nebo "\e+0" ...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
2.1. 11:08 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Dík za doplnění. Zvláštní je, když na to koukám, že ncurses vždy nastaví znakovou sadu ve slotu 0, vykreslí znak(y) a přepne slot 0 zpátky na normální text, a to i když kreslí jen jeden znak rámečku. Takže v případě vykreslení jednoho rámečkovýho znaku, což se děje u svislých čar, to dělá 7 bajtů, což je horší než ten Unicode. Kdyby to místo toho na začátku při nastavování terminálu nastavilo rámečkovou znakovou sadu v druhým slotu a pak jen přepínalo mezi sloty (pomocí shift in / shift out bajtů), tak by to byly jen 3 bajty při kreslení jednoho znaku (a ~1 bajt při kreslení delší vodorovný čáry).

By mě zajímalo, jestli pro to mají nějakej důvod, nebo jestli to jen prostě nikdo nezoptimalizoval...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
2.1. 12:12 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Co mám tak ponětí, tak se ncurses tohle nesnaží optimalizovat - horizontálních čar není zas až tolik.

Naopak pomocí double bufferingu se to snaží nepřekreslovat stejná místa, případně identifikovat horizontální skrolování a použít efektivní blokové operace při skrolování.

Další otázkou je jak to kreslí mc - jestli znak po znaku nebo jestli používá primitiva pro kreslení boxů. Těžko říct.
Josef Kufner avatar 30.12.2019 18:54 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Taky ta averze k binárním formátům je historický omyl …

Kdepak. Je to nedostatkem nástrojů a omezenými zdroji prakticky všude – bavíme se o době, kdy editor ed byl špičková technologie a kabelový přenos spočíval v roli děrného pásku či balíku disket odneseným v kabele.

Na debugovaní textového protokolu stačí komunikaci sypat na terminál či na klávesnici ručně naťukat. Nemusíš vyvíjet ladicí nástroje, nemusíš je distribuovat, nezabírají místo. Například HTTP server nebo POP3 server oťukáš velmi snadno telnetem a hned víš, co se kde rozbilo. FTP se dokonce po telnetu dá reálně používat (i když bych to asi dobrovolně nedělal). Také se záznam takové komunikace dobře popisuje a vysvětluje v papírové knize.

Teprve s rozvojem všech nástrojů a zvýšením výpočetního výkonu nad úroveň kalkulačky se celkem nedávno přišlo na to, že binární věci mohou být také docela použitelné.
Hello world ! Segmentation fault (core dumped)
xkucf03 avatar 30.12.2019 16:22 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Všechny ty příklady mi zatím přijdou dost umělé a šly by vyřešit mnohem jednodušeji jinak.

Já sám to používám docela dost, ale často to jsou různé interní věci, které (ještě) nechci zveřejňovat nebo je to hodně specifické, co by vytržené z kontextu jako příklad nebylo moc pochopitelné. Jinak ale souhlasím a snažím se vymýšlet praktičtější příklady.

Teď zrovna to používám tak, že mám CSV soubor a v něm si vytvářím nějaká data. Momentálně je zadávám v LibreOffice Calc, protože je to nejpohodlnější, ale tím, že je to obyčejný textový soubor v jednoduchém formátu, tak nejsem závislý na žádném komplexním softwaru, jako je kancelářský balík, a vím, že kdykoli můžu pokračovat v práci v Emacsu, mceditu nebo čemkoli jiném. A tenhle CSV soubor si čtu pomocí relpipe-in-csv a pak z něj můžu něco generovat, spouštět pro každý řádek nějaký shellový příkaz, mít k tomu nějaké testy/kontroly pro zajištění konzistence, filtrovat to, řadit, kreslit diagram v GraphVizu nebo grafy v Gnuplotu atd. Jde taky o to, že na začátku často nevím, co všechno s těmi daty budu dělat a jak robustní to chtít mít – takhle se dá začíst s málem, jedním CSV souborem, a buď to u něj zůstane, nebo postupně přidám další věci kolem toho, jak je potřeba.

Tzn. může to sloužit i pro různé osobní agendy nebo jako pomocný nástroj při tvorbě něčeho dalšího.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 30.12.2019 16:57 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Tak zrovna na analýzu CSV je hromada nástrojů. V Pythonu to hodím do Pandasu a udělám si s tím co potřebuju. A vlastně tohle lze napsat na cokoliv, na xml je hromada nástrojů, na json, připojit se k libovolné DB umí kdejaký program pro analytiky už několik desítek let atd. Takže se to trochu vlamuje do otevřených dveří.

Ale jako nenech se odradit, já tyhle projektíky mám rád, každý máme něco podobného a málokdo s tím jde s kůží na trh a pokud je to pro tebe užitečné, tak je to fajn.
30.12.2019 18:36 _
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jediná přidaná hodnota relpipes je NIH (pro tebe samozřejmě, ale psal jsi že jsi asi jediný uživatel)
Bedňa avatar 30.12.2019 17:49 Bedňa | skóre: 34 | blog: Žumpa | Horňany
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Začal by som to používať keby to bolo ľudskejšie.

Zápis:
    relpipe-in-xmltable \
        --relation 'policy' \
            --records '/busconfig/policy/allow|/busconfig/policy/deny' \
            --attribute 'policy'           string 'name()' \
            --attribute 'user'             string '../@user' 
            ...
\
Toto je proste hrozné jak celé XML

Ja som programoval niečo podobné, ale s tým že si to vyťahalo všetky tagy a atribúty samo (proste jeden príkaz) a potom na to môžeš nasadiť hocijaký GNU nástroj.

Čo sa týka Heronovej kritiky ("sweet spot"), tak má pravdu. Ale chápem ťa, už par krát som robil prezentáciu nejakých projektov a vždy z toho vyliezlo niečo čomu chýbal ťah na bránu. Proste všetko dobré a chýba tomu aby ľudia vstali zo stoličiek a tlieskali.

Good luck.
KERNEL ULTRAS video channel >>>
xkucf03 avatar 30.12.2019 23:50 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Toto je proste hrozné jak celé XML

A jak bys jinak řešil převod stromu na relace? Tohle je ještě dost přívětivé – jedním XPath výrazem vybereš záznamy a dalšími XPath dotazy vybereš atributy. Tohle nelze namapovat nějak automaticky – některé atributy (relační) hledáš v elementech, některé v atributech (XML), některé někde hlouběji v potomcích, jiné zase v nadřazených uzlech. Ostatně totéž se používá v databázích a i se to i stejně jmenuje.

Ja som programoval niečo podobné, ale s tým že si to vyťahalo všetky tagy a atribúty samo (proste jeden príkaz) a potom na to môžeš nasadiť hocijaký GNU nástroj.

Jasně, jde to celé nasypat do jednoho seznamu1 obsahujícího klíče a hodnoty. Jenže z toho si pak záznamy splňující určitou podmínku jen tak negrepneš, protože ten záznam je zapsaný na více řádcích. Šlo by to nějak v AWKu nebo Perlu, kde bys pracoval nad těmi více řádky, ale rozhodně by to nebylo jednodušší než tohle.

A pak je samozřejmě možnost se na nějaké relace vykašlat a pracovat s tou původní stromovou strukturou. V případě XML je to často nejlepší možnost – napíšeš jeden XQuery FLWOR výraz a máš hotovo.

Čo sa týka Heronovej kritiky ("sweet spot"), tak má pravdu. Ale chápem ťa, už par krát som robil prezentáciu nejakých projektov a vždy z toho vyliezlo niečo čomu chýbal ťah na bránu. Proste všetko dobré a chýba tomu aby ľudia vstali zo stoličiek a tlieskali.

Největší problém je, že to přichází s asi dvaceti- nebo třicetiletým zpožděním. Ale podle mého to má smysl i dnes. A před těmi třiceti lety jsem fakt nebyl schopný nic takového napsat :-) ani před dvaceti. Přitom podobné myšlenky se v průběhu těch let opakovaně objevovaly.2 Akorát to nikdo nedotáhl do široce použitelného stavu. Tak uvidíme, jestli se to povede mně.

[1] záměrně nepíši mapa, protože záleží na pořadích a to se v mapách většinou ztrácí
[2] a je zajímavé, jak těžké je to v hlubinách internetu najít – samozřejmě jsem si na začátku dělal rešerši existujících řešení, ale hodně jsem jich našel až v průběhu práce a víceméně náhodou

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 31.12.2019 10:05 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Přitom podobné myšlenky se v průběhu těch let opakovaně objevovaly.
Což vůbec neznamená, že jsou správné. Naopak, pokud se běžná praxe bez nich obešla, tak to znamená, že jejich potřeba je dost nízká až mizivá.

Jako admin jsem zažil mnoho situací, kdy někdo přišel s nějakým nástrojem (velmi pěkně zpracovaným) a přesvědčoval nás, že to nutně potřebujeme a vyřeší to všechny naše problémy. Pokud už se to ze zvědavosti nasadilo, tak to vydrželo tak den a druhej to šlo pryč a za 14 dnů už si na to nikdo ani nevzpomněl. Úplně nejhůř bylo ve chvílích, kdy byl šéf o jejich prospěšnosti marketingem přesvědčen natolik, že se to nasadilo trvale.

A ten problém není v těch nástrojích. Já nemám pochybnost o jejich kvalitě (no, i když...). Problém je v tom, že se totálně míjí s běžnou praxí a s běžnými potřebami těch adminů. A krásně je to vidět na pořadech typu DragonsDen. Lidé bez dlouhé praxe v daném oboru většinou přijdou s výrobkem možná hezky zpracovaným, ale totálně mimo.

Když si půjčím jiný tvůj komentář:
Ty myšlenky by se měly postupně objevit v implementaci Relačních rour (např. pohled na systémové procesy, uživatele, disky atd. formou relací, nad kterými lze pak provádět SQL dotazy, nebo AWK, Scheme, Python, dle vkusu každého… zatím je implementovaný jen pohled na fstab/mtab jako ukázka).

Já jsem nikdy nepotřeboval žádný "relační" pohled na tato data. Na běžném systému adminovi stačí ps aux, cat /etc/fstab, mount, koukne a vidí. A pokud je některých položek větší než malé množství (třeba těch uživatelů), tak už dneska na to existují řešení (třeba ldap). Ale stejně se v 99% případů použije standardní id.
xkucf03 avatar 31.12.2019 11:24 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Já jsem nikdy nepotřeboval žádný "relační" pohled na tato data. Na běžném systému adminovi stačí ps aux

A jak v těch procesech vyhledáváš? Běžně se používá:

ps aux | grep …

ale to ti najde i spoustu věcí, které nechceš, včetně procesu toho grepu, kterým právě hledáš. Takže tu máme trik s regulárním výrazem:

ps aux | grep [j]ava

čímž se ten proces grepu odfiltruje, ale stále tam máš všechny procesy, u kterých se kdekoli, třeba v parametrech nebo ve jménu uživatele vyskytuje slovo java. A zrovna jeden z mých uživatelských účtů má v názvu java.

Pak si můžeš vzít na pomoc AWK:

ps aux | awk '($11 ~ /java$/)'

ale tam si zase musíš pamatovat pozice jednotlivých sloupců.

A pokud se v názvu (nebo jiném sloupci, který prohledáváš) vyskytuje mezera, tak se ti to celé rozpadne, vyhledáváš jen v části před mezerou a následující „sloupce“ se posunou, přečíslují. Ten systém v tobě vlastně vzbuzuje nějaké naděje, že to je jednoduché a spolehlivé, ale když to začneš reálně používat, tak narážíš na další a další případy, kdy to nefunguje a už to není tak skvělé a jednoduché, jak to vypadalo na začátku.

Přijde mi, že kvůli těmto „drobným nedokonalostem“ spousta lidí utíká od unixu ke klasickému programování. Podle mého je to škoda a ten potenciál unixových systémů bych rád využíval a odstranil některé jeho chyby. Nebo se můžeme na celý unix, příkazy, roury a virtuální souborové systémy poskytující různé informace vykašlat a mít jen nějaké objektové či funkcionální API, které se bude volat třeba z toho Pythonu nebo jiného programovacího jazyka.

Potom v procps-ng existuje volba -C, kterou lze vyhledávat podle příkazu. Ale třeba ve FreeBSD volba -C znamená „Change the way the CPU percentage is calculated…“. A i když máme v systému zrovna ps s volbou -C, která hledá, tak to znamená, učit se pro každý příkaz jeho specifickou syntaxi pro filtrování. To je taky v rozporu s doporučením, že by jeden program měl dělat jednu věc a měl by ji dělat dobře. Tam, kde je dat málo a není potřeba nějak extra optimalizovat, je mi daleko bližší přístup, kdy se to oddělí: 1) příkaz, který získává/generuje data a 2) univerzální filtrovací příkaz – u kterého se člověk jednou naučí jeho syntaxi a může pak hledat v libovolných datech.

cat /etc/fstab, mount, koukne a vidí

Příkaz mount nebo cat /etc/mtab mi na první pohled moc neřekne – ty řádky splývají dohromady a nedokáži očima/hlavou snadno parsovat jednotlivé hodnoty oddělené mezerami. Ale když si dám:

cat /etc/mtab | relpipe-in-fstab | relpipe-out-tabular

tak v tom mnohem lépe najdu, co potřebuji, většinou to vidím na první pohled a už to nemusím filtrovat žádným nástrojem.

Totéž platí pro ten /etc/fstab. Většinou to tedy ručně zarovnávám do sloupců pod sebe, aby se v tom dalo aspoň trochu vyznat, ale to je ruční práce navíc – a někdy je ten soubor generovaný nebo ho psal někdo jiný, takže je to nepřehledné. Pak můžu udělat:

ssh example.com cat /etc/fstab | relpipe-in-fstab | relpipe-out-tabular

a zase to vidím mnohem přehledněji. V cyklu se to dá udělat pro více serverů a pak výsledky nějak agregovat… Samozřejmě netvrdím, že čtení fstabu je nějak zábavná nebo významná činnost – je to jen příklad a ukázka toho principu – a chtěl jsem začít s něčím co nejjednodušším.

Ještě co se týče toho vykašlání se na unix: celkem souhlasím s Bystroušákem – taky by se mi líbil objektový OS. Ale je to implementačně výrazně složitější, než unix vylepšený o datový formát, kterým se dají rourami předávat relační data.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 31.12.2019 12:17 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
A jak v těch procesech vyhledáváš?
Přesně jak jsi popsal. Pokud je výpis ps, top, htop příliš komplikovaný (což většinou není), tak | grep zafunguje na drtivou většinu zbylých případů. Ty jednotky zbývajících případů se vyřeší jinak.

Navíc s nástupem kontejnerů je použití filtrů potřeba ještě méně. Ve FreeBSD mám všechno v jailech a když dám v jailu ps aux, tak se to pohodlně vejde na jednu obrazovku a jsou tam jen služby, které jsou v tom jailu, tedy typicky jedna až dvě:
[root@backup ~]# ps aux
USER       PID %CPU %MEM   VSZ   RSS TT  STAT STARTED    TIME COMMAND
root     61929  0.1  0.0 13208  3904  0  SJ   11:36   0:00.01 /usr/local/bin/bash -i
root     34211  0.0  0.0 11356  1676  -  IsJ   4Dec19 0:04.80 /usr/sbin/syslogd -s
backuppc 34271  0.0  0.0 28552 11428  -  IJ    4Dec19 0:17.34 /usr/local/bin/perl /usr/local/bin/BackupPC -d
root     34277  0.0  0.0 16808  2916  -  SsJ   4Dec19 0:50.89 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34280  0.0  0.0 16832  4140  -  IJ    4Dec19 0:00.01 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34282  0.0  0.0 16832  3988  -  IJ    4Dec19 0:00.01 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34284  0.0  0.0 16756  2804  -  IJ    4Dec19 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
root     34288  0.0  0.0 11272  1452  -  SsJ   4Dec19 0:09.13 /usr/sbin/cron -s
backuppc 34319  0.0  0.0 16808  2928  -  IJ    4Dec19 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34323  0.0  0.0 16860  4064  -  IJ    4Dec19 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34324  0.0  0.0 16808  2928  -  IJ    4Dec19 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34326  0.0  0.0 16860  4192  -  IJ    4Dec19 0:00.01 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34327  0.0  0.0 16860  4172  -  IJ    4Dec19 0:00.01 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34328  0.0  0.0 16808  2928  -  IJ    4Dec19 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
backuppc 34329  0.0  0.0 16808  2928  -  IJ    4Dec19 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
root     61930  0.0  0.0 11772  2764  0  R+J  11:36   0:00.00 ps aux
Na první pohled: apache a backuppc + omáčka jako cron a syslog, konec.

Výpis procesů na hostitelském systému ps aux -J 0, tedy bez jailů, obsahuje vlastně jen kernel thready a ssh (+ syslog a cron). Na to nepotřebuju filter.
Ten systém v tobě vlastně vzbuzuje nějaké naděje, že to je jednoduché a spolehlivé, ale když to začneš reálně používat, tak narážíš na další a další případy, kdy to nefunguje a už to není tak skvělé a jednoduché, jak to vypadalo na začátku.
Já to reálně používám už asi 20let a fakt to není problém. A díky jiným postupům je tlak na to filtrování ještě mnohem menší. Rozdělení do virtuálek, kontejnerů apod. logické rozdělení, které přináší i mnoho dalších jiných výhod a které zjednodušuje i některé věci původně možná složité nebo nepřehledné
Nebo se můžeme na celý unix, příkazy, roury a virtuální souborové systémy poskytující různé informace vykašlat
To je podle mě chybný závěr. Unixový přístup je skvělý, ale bash není jediný způsob, jak jej docílit. Dělat malé jednoduché a snadno komunikující programy lze i jinak, než nutně jen pipe v shellu. Třeba ten můj příklad s workery na síti, které používají centrální frontu a centrální úložiště. Každý worker si udělá jen tu svou část a výsledek uloží do úložiště a klidně může do fronty přidat další krok a následně se ukončí. Malé prográmky, které si udělají to svoje a komunikují mezi sebou. Není to jediný koncept, funguje to na data, která chci zpracovávat (tedy nezávislé datové balíky) ale je to unixové stejně jako pipe v shellu. Které pochopitelně nezatracuju a využívám také, ale nejsou pro mě svatý grál.
Totéž platí pro ten /etc/fstab. Většinou to tedy ručně zarovnávám do sloupců pod sebe, aby se v tom dalo aspoň trochu vyznat, ale to je ruční práce navíc – a někdy je ten soubor generovaný nebo ho psal někdo jiný, takže je to nepřehledné.
To tam máš stovky položek vygenerovaných z různých zdrojů?

Takto vypadá fstab na mém soukromém největším serveru na FreeBSD:
# Device        Mountpoint      FStype  Options Dump    Pass#
/dev/ada0p2     /               ufs     rw      1       1
fdesc   /dev/fd         fdescfs         rw      0       0
proc    /proc           procfs          rw      0       0
/dev/ufs/ports-system /usr/ports  ufs rw 0 2
/dev/ufs/ports-svn /usr/ports-svn ufs rw 0 2
Jsou tam tři device a dva virtuální fs. Kdybych neměl oddělený port tree na samostatných oddílech, je tam reálně jeden, první, řádek. Data jsou na ZFS a ten se do fstabu vůbec nezapisuje.

Na linuxu je to ještě jednodušší. Jeden rootfs na btrfs. Tečka. Díky tomu, že btrfs subvolume se v user space tváří stejně jako adresáře, tak není potřeba mít ve fstabu žádné další extra položky. Díky těmto technologiím fstab prakticky postupně ztratil smysl. Kdyby kernel uměl zjistit, který btrfs fs (pokud je jich tam víc) má být rootfs, tak může být fstab prázdný. Pokud je tam jen jeden, tak je default subvolume jen jedna (A freshly created filesystem is also a subvolume, called top-level, internally has an id 5. This subvolume cannot be removed or replaced by another subvolume. This is also the subvolume that will be mounted by default, unless the default subvolume has been changed (see subcommand set-default).) a je to rootfs.
a zase to vidím mnohem přehledněji. V cyklu se to dá udělat pro více serverů a pak výsledky nějak agregovat… Samozřejmě netvrdím, že čtení fstabu je nějak zábavná nebo významná činnost – je to jen příklad a ukázka toho principu – a chtěl jsem začít s něčím co nejjednodušším.
Ano, to je super příklad, a za celou praxi jsem to potřeboval asi tak 3x, kdy jsem měl za úkol to zpracovat pro někoho jiného, kdo si myslel, že ta data nutně potřebuje a nemůže bez nich žít. Pochopitelně nepotřeboval a ani se v nich nevyznal. Protože kdyby se v nich vyznal, tak by současně i věděl, jak si je zjistit sám. Napsat for přes seznam serverů a ssh $server command umí každý levou zadní.
31.12.2019 13:36 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
A jak v těch procesech vyhledáváš?
pgrep
Digitalizace starých listin je přesun informací z šanonu do shannonu.
31.12.2019 13:02 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jde o to jak má člověk nastavené myšlení - já jako programátor jsem dost často narážel právě na to, že roury v Unixu jsou nestrukturované. Ten koncept je geniální, ale nikam zvlášť se neposunul a v důsledku toho má každá utilita vyšší desítky přepínačů a stejně se musí ještě dost používat awk nebo sed a psát na míru regulární výrazy. Pokud má člověk trochu technického citu, tak by měl vnímat jak je vše přeplácané, překomplikované, jak chybí jednotící koncepty. Vůbec nejde o to, že by věci nefungovaly - to po 40 letech vývoje a nasazení v miliardách zařízení by bylo smutné, ale jako celek to ztrácí eleganci.

Unix je geniální koncept - ale skoro padesát let starý. Skoro všechno na něm by stálo za revizi a to brutální (posledních pár let jsem si hrál s terminálovými aplikacemi, a když se člověk dostane dost blízko, tak je to taková hromada sraček, že se člověk dost musí divit, že to přesto funguje. Vyžaduje to enormní úsilí pár lidí, kteří to nějak udržují při životě. Bohužel, dokud to úplně nespadne, tak se do toho nikdo nepustí, protože by se musela zahodit zpětná kompatibilita a znamenalo by to desítky let vývoje.
31.12.2019 13:13 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jestli není problém v tom, že použít tu kterou utilitu se správnými přepínači je furt jednodušší, než vyrábět všechno odznovu a doufat, že se ty jednotící koncepty trefí do toho, jakým způsobem funguje ten který počítačový systém.
Quando omni flunkus moritati
Josef Kufner avatar 31.12.2019 13:21 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
To je takové uvíznutí v lokálním minimu. Takové řešení sice představuje nejmenší množství práce pro dosažení cíle, ale pokud by se roury trochu překopaly, tak by té práce mohlo být potřeba výrazně méně. Tedy o kousek vedle je ještě menší minimum, ale cesta vede přes kopec práce.

Otázkou je, jak by takové jednotné struktury měly vypadat a jak to udělat upravitelné a rozšiřitelné do budoucna.
Hello world ! Segmentation fault (core dumped)
31.12.2019 13:40 sigma
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Příklad jak to (ne)udělat je PowerShell. Podle mě v mnoha ohledech povedený. Roury jsou objektové, a spousta systémových věcí je dostupná přes jednotné objektové API.

Takový /proc na Linuxu umí dost potrápit - různé oddělovače, když je některý sloupec prázdný nebo obsahuje mezery, tak se to parsuje dost špatně...
Josef Kufner avatar 31.12.2019 13:52 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
No… s objektama se to nesmí přehánět. U datových struktur mi tabulkový přístup přijde lepší. Hezky to je vidět na SQL, kde je všechno tabulka a používá se to dobře, tedy než dojde na stromová data.
Hello world ! Segmentation fault (core dumped)
Heron avatar 31.12.2019 14:31 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
ale pokud by se roury trochu překopaly
Ale proč by se měly překopávat? Roury umožňují přenést libovolný "protokol" a kdo chce (třeba Franta) si může kolem toho postavit vlastní utility, které budou komunikovat domluveným protokolem přes roury (a to klidně i přes net cat nebo rourou do nebo z ssh).
Tedy o kousek vedle je ještě menší minimum, ale cesta vede přes kopec práce.
Otázkou je, jestli to vedlejší minimum není minimem pro mnohem menší množinu případů, než to aktuální.
Josef Kufner avatar 31.12.2019 14:40 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Nejde o prekopání samotných rour, ale o ty programy, které je používají. Problém je v tom, že není standardní protokol, který by jednotlivé programy mohly používat, a proto každý program má hromady přepínačů na různé formátování výstupu. Pokud by byl definován protokol, tak by přepínač stačil jeden na přepínání mezi lidským a strojovým formátem. A pokud by ten protokol byl opravdu dobrý, tak by nebylo potřeba ani to – viz mikroformáty na webu.
Hello world ! Segmentation fault (core dumped)
Heron avatar 31.12.2019 15:08 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Pořád mám pocit, že se tady řeší problém, který reálně neexistuje (nebo je pod moji rozlišovací úroveň). Vůbec nic nikomu nebrání udělat to, co jsi napsal. Klidně mohou vznikat utility, které budou spolupracovat přes sdílený protokol. Franta už to píše.

Ale já si opravdu nemyslím, že je po tom taková poptávka. Stávající textové výstupy klasických 40 let starých unixových příkazů jsou dostatečné jak pro člověka, tak i pro další strojové zpracování přiloženými filtry. Filtry jsou natolik obecné, že je lze používat i na hromadu dalších věcí. A pokud někdo už dneska nutně potřebuje mít určitá data ve strojově čitelné podobě (viz třeba ty uživatele apod), tak už to dneska existuje.
a proto každý program má hromady přepínačů na různé formátování výstupu
No, ehm, ono je to totiž strašně jednoduché. Já sám nemám rád programy s přeplácanými volbami, ale u jednodnoho programu jsem doplnil výstup json (protože to někdo chtěl), takhle extrémně složitě:
with open(filename, 'w') as work_file:
    json.dump(self.dataset, work_file, indent=4)
O pár modulů vedle zase někdo chtěl CSV:
csv_file = StringIO()
csv_writer = csv.writer(csv_file, quoting=csv.QUOTE_NONNUMERIC)
dataset = self.dbs.export_data()

for record in dataset:
    csv_writer.writerow(record)

print(csv_file.getvalue())
csv_file.close()
Jako ono je to fakt trivka, přes Click přidat další volbu cli --export-json a napsat dva řádky.
31.12.2019 15:32 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
+1, od začátku do konce
Quando omni flunkus moritati
xkucf03 avatar 31.12.2019 15:33 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jako ono je to fakt trivka, přes Click přidat další volbu cli --export-json a napsat dva řádky.

Jen pro zajímavost: ta knihovnička pro parsování CLI parametrů má více řádků kódu než všechny moduly Relačních rour dohromady (a to chci řadu věcí ještě pročistit a refaktorovat, občas je tam duplicitní kód).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 15:47 _
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jen pro zajímavost: ta knihovnička je dobře zdokumentovatá, solidně pokrytá testy a někdo ji používá.
Heron avatar 31.12.2019 15:51 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jen pro zajímavost: ta knihovnička pro parsování CLI parametrů má více řádků kódu než všechny moduly Relačních rour dohromady
Ano, to je možné. A? Pro mě je počet řádků zajímavý až teprve po té, co ten program nebo modul dělá co má. A jestli Click potřebuje více řádků kódu než jiný projekt, není pro mě nijak podstatné. (Navíc ten modul dělá o hodně víc, než jen parsing cli parametrů.) A dělá to skvěle, na rozdíl třeba od ArgParse ve standardní knihovně. Počty řádků začnu porovnávat teprve až tehdy, až tu bude jiný projekt, který bude umět min. totéž. a stejně dobře. Aby bylo co srovnávat.
Josef Kufner avatar 31.12.2019 15:58 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jak už jsem psal, uvízli jsme v lokálním minimu. Poptávka po jednotném protokolu není a nebude, dokud ho nebude podporovat nadkritické množství programů, tedy než přelezeme ten kopec práce. Na to je potřeba takový protokol standardizovat a protlačit všude možně. Až bude podpora všude možně, tak to použití bude jednodušší a bude stát za to se to naučit používat místo grepu a sedu.
Hello world ! Segmentation fault (core dumped)
1.1. 15:39 johnyK
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
ja jsem take toho nazoru, ze ty roury jsou dobre pouzitelne.

Pri te cele diskuzi mi napada ale jedno - rekl bych nejdulezitejsi co zatim nikdo nezminil. Ja za ta desetileti, co se motam kolem programovani a administrovani bych rekl, at uz je neco co pouzivam k reseni problemu na 2 radky nebo na 100 radku, tak co tam musi byt vzdycky je komentar, co to dela.

A proto pouzivam i na jednoradkove prikazy, treba pospojovane pres pipe vzdycky shell scripty, kde je mnohem vice komentare nez kodu. Tedy krome uplne primitivnich veci jako jiz zminene ps ax | grep xxxxx

31.12.2019 23:09 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
ale pokud by se roury trochu překopaly
Ale proč by se měly překopávat?
+1. Implementovat si protokol pro roury určitě je možné, ale IMO to nemá moc smysl - roury na tohle IMO nejsou dobrá úroveň abstrakce. Roury jsou primitivní ze své definice.

Pokud chce někdo pracovat s proudy strukturovaných dat, tak na to jsou určené programovací jazyky, v kontextku diskuze by mohl být vhodný např. nějaký funkcionální skriptovací jazyk. "Překopat roury", tak jak tu někteří píší, by v podstatě IMO vedlo nutně k vytvoření něčeho takového.

Proč radši místo toho nestáhnout třeba PureScript nebo tak něco a nezačít vesele hackovat? ;-)
Digitalizace starých listin je přesun informací z šanonu do shannonu.
31.12.2019 23:54 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Asi všichni, co tu jsme umíme programovat. Nicméně síla rour je v možnosti vytváření jednoduchých jednořádkových programů. Navíc pokud začnu programovat, tak už vytvořit sekvenci volání externích aplikací bude téměř vždy méně čitelné než když totéž udělám v shellu. Nebo musím připravené knihovny - ale to už znamená určitou magii a schovávání výkonné části. Pokud je základním stavebním prvkem operačního systému aplikace, pak přirozeným lepidlem je shell, nikoliv jakýkoliv vysokoúrovňový jazyk. Něco jiného by bylo, kdyby byl operační systém poskládaný z objektů - a aplikace by byly jen jednou z interface objektů. Pak by vyšší jazyky dávali smysl.
1.1. 01:15 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Asi všichni, co tu jsme umíme programovat. Nicméně síla rour je v možnosti vytváření jednoduchých jednořádkových programů.
Souhlasim, nicméně IMO ty programy jsou jednoduché a jednořádkové právě mj. díky primitivnosti rour, resp. obecně těch rozhraní... Jakmile začneš řešit složitější věci, dojdeš celkem rychle k momentu, kdy to v nějakém skriptovátku typu Python je snazší...

Samozřejmě je možné znásilňovat roury, grepy, sedy, awky atd. ad infinitum (koneckonců, třeba sed a awk jsou jistě turing-complete) ... ale elegantního na tom není IMO vůbec nic ...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
1.1. 08:02 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
To už se točíme v cyklu. Jelikož jsou tyto nástroje primitivní, tak jsou pro složitější věci nevhodné. Ale primitivní být nemusí. Byly navržené v době, kdy nadupané počítače měly 256MB paměti, a na vymýšlení sofistikovanějších konceptů nebyl prostor. V databázích by to bylo stejné, jako kdybychom stále používali SQL 87 a rule based optimalizátory a tvrdili, že na nic složitějšího se to nehodí, protože složitější dotazy jsou nepřehledné a pomalé.
Josef Kufner avatar 1.1. 12:43 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Byly navržené v době, kdy nadupané počítače měly 256MB paměti
Jsi o pár řádů vedle ;-)
Hello world ! Segmentation fault (core dumped)
1.1. 14:11 kralyk z abclinuxu | skóre: 29 | blog:
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jelikož jsou tyto nástroje primitivní, tak jsou pro složitější věci nevhodné. Ale primitivní být nemusí.
No já si právě myslim, že by měly zůstat primitivní. Jakmile primitvní nebudou, tak už nebudou mít ten hodně obecný záběr, obecnou použitelnost a kompatibilitu...
Digitalizace starých listin je přesun informací z šanonu do shannonu.
Heron avatar 31.12.2019 14:22 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
roury v Unixu jsou nestrukturované
Je to primitivum pro spojení stdout jednoho procesu se stdin druhého. Co si ty programy budou posílat už je na nich. Tradičně to byl textový výstup, já osobně mnohem více posílám binární data (cat /dev/sda | lzop | nc backup). To je dělá univerzálními a obecně použitelnými. (Nehledě na fakt, že se takto jednoduše bez práce dosáhne určité paralelizace, protože všechny procesy běží současně a na pipe je buffer, o který se stará shell.)
v důsledku toho má každá utilita vyšší desítky přepínačů
Úplně nechápu, jak počet parametrů souvisí s rourama. Jako že kdyby roury fungovaly jinak, bylo by možné programy rozdělit na menší a propojit je? To jistě u některých bude možné, ale nikoliv obecně.
Pokud má člověk trochu technického citu, tak by měl vnímat jak je vše přeplácané, překomplikované, jak chybí jednotící koncepty.
S tou přeplácaností a komplikovaností nevím, ale možná je to tím, že pracuju v jiné podmnožině. Nářky na jednotící koncept jsou slyšet poměrně často, ale ještě nikdo neřekl, co vlastně chce a jak by to fungovalo napříč všemi nasazeními linuxu. Já to vnímám tak, že dnešní linux / unix poskytuje kostičky lega, které možná nejsou dokonalé, ale lze jimi vyplnit celý prostor. Některé "sjednocené" koncepty by možná byly vhodnější pro nějaká konkrétní nasazení, ale ne pro celek.
Unix je geniální koncept - ale skoro padesát let starý. Skoro všechno na něm by stálo za revizi a to brutální (posledních pár let jsem si hrál s terminálovými aplikacemi, a když se člověk dostane dost blízko, tak je to taková hromada sraček, že se člověk dost musí divit, že to přesto funguje. Vyžaduje to enormní úsilí pár lidí, kteří to nějak udržují při životě. Bohužel, dokud to úplně nespadne, tak se do toho nikdo nepustí, protože by se musela zahodit zpětná kompatibilita a znamenalo by to desítky let vývoje.
O tom bych si rád přečetl něco víc. Vím, že jste dělal pspg , možná by stálo za to sepsat něco ze zákulisí.
31.12.2019 15:33 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Skrz roury jdou jenom data a zpracování je víceméně jednosměrné. Což je implementačně jednoduché, ale náročné na parametrizaci. Já musím v místě, kde mi vznikají data nastavit skrz parametry, co chci dostat za výstup. Kdyby roury byly inteligentnější, tak by se tyto parametry daly odvodit z požadovaného finálního výstupu. Uvedu analogii s Postgresem a FDW. Pokud v postgresu napíšu dotaz nad cizí tabulkou, tak mi Postgres dokáže izolovat predikát (případně další operace), které se váží na cizí tabulku, a tento predikát pushnout do místa, kde mi data vznikají. Nemusím to dělat ručně. Pokud bych měl v Unixu filtr, který dokáže agregovat a grupovat podle nějakých atributů, tak by bylo hezké abych mohl napsat "zdroj | sum(xx) groupby(yyy) | graph bar". Zdroj by dostal jiným kanálem informaci, že se po něm požadují atributy xxx, yyy. Tím by mohla odpadnout parametrizace zdroje i finálního konzumenta (protože ten by jiným kanálem dostal metadata).

K tomu terminálu - podívejte se na escape sekvence VT xxx. Dnes jsou terminály dost komplikované aplikace právě kvůli variabilitě různých escape sekvencí, kterou musí implementovat - a stejně je to dost omezené. Od této komplexity vás izoluje ncurses, což je další docela velký bazmek, která toho zase až tolik neumí, a od některých detailů Vás stejně neušetří. Tato knihovna existuje 2x - s podporou wide chars a bez podpory. Když ale pracujete s UTFkem a speciálními znaky, tak pak zjistíte, že něco musíte zobrazovat jako utf, něco jiného jako wide char. Narazíte na to, že si třeba double click musíte implementovat sám, protože ta vestavěná implementace je hodně omezená. A to všechno kvůli tomu, abyste na nějakou pozici zobrazili určitý znak. U některých znaků se dodnes neví jestli se mají zobrazovat o dvojnásobné nebo jednoduché šířce. Některé escape sekvence jsou 2x s tím, že na jednom terminálu fungují a na jiném nefungují (nebo v jednom prostředí fungují a v jiném nikoliv). V pspg jsem řešil stíny pod menu - je to taková banalita, ale najít funkční řešení mi trvalo několik dní. Atributy znaků se trochu jinak chovají, když máte 8, 16 nebo 256 barev. V ncurses máte např. panely (překryvná okna), které mají z vrstvu, nicméně stejně musíte používat malířův algoritmus, protože to nefunguje všude, ... prostě se tam neustále naráží na banality, které povětšinou mají základ v té neuvěřitelné různorodosti terminálů, které jsou podporované. Je to ale ohromná koule na noze. PTY je jiné, když aplikaci nastartujete v terminálů než když např jedete v tmuxu. atd atd
31.12.2019 15:56 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Hezké by to bylo, ale je otázka, jestli si to hafo potřebné práce na sebe vydělá, tj. jestli se najde dost lidí, kterým to práci ušetří tak často, aby to mělo cenu vyrábět. Nejsme v matematice, abychom něco dělali, protože je to hezké... Protože když někdo používá "zdroj | sum(xx) groupby(yyy) | graph bar" tak často, aby se vyplatilo řešit nějaké přenášení metadat, nejspíš už si pamatuje, že má použít --i-want-xx --want-yyy-too

Ten příklad s Postgresem a FDW bych nechal stranou, tam IMO nepůjde o to, aby se něco nemuselo dělat ručně, ale aby to běhalo rychle.

Terminál s rourami zase až tak moc nesouvisí, maximálně tím, že je v něm používáte nejčastěji. Nebudu rozporovat, že současný stav je to děs a běs, ale roury za to nemůžou a nápravu taky brzdí něco jiného...
Quando omni flunkus moritati
Heron avatar 31.12.2019 16:29 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Hezké by to bylo, ale je otázka, jestli si to hafo potřebné práce na sebe vydělá, tj. jestli se najde dost lidí, kterým to práci ušetří tak často, aby to mělo cenu vyrábět. Nejsme v matematice, abychom něco dělali, protože je to hezké... Protože když někdo používá "zdroj | sum(xx) groupby(yyy) | graph bar" tak často, aby se vyplatilo řešit nějaké přenášení metadat, nejspíš už si pamatuje, že má použít --i-want-xx --want-yyy-too
No hlavně to jde napsat triviálně už dnes (psql -c 'select sum(x) from neco where ... group by ...' | graph bar') s tím, že má k disposici kompletní bohatost jazyka SQL, která by se pomocí pipe a předávání metadat dost těžko v shellu dosahovala. A navíc je otázkou, kolik lidí by nový způsob používalo místo SQL, které by ale stejně museli umět.
31.12.2019 18:09 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
SQL můžu použít na data, která už mám v databázi. Pokud je v databázi nemáte, tak je tam musíte naimportovat, a to už je nějaká práce navíc.
Heron avatar 31.12.2019 16:13 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Díky. Jasně, tomuto rozšíření rour rozumím a jak jste to napsal to dává smysl. Ale nesouhlasím s tím.
Zdroj by dostal jiným kanálem informaci
Osobně dávám vždy přednost explicitnímu před implicitním. Takže pokud napíšu zdroj | filter, tak očekávám, že zdroj pošle všechna data i kdyby si z nich filter vzal jeden byte (krom případu, že se filter ukončí a tím zruší i tu pipe a ten proces před ním). Neočekávám, že se stane zdroj --filter neco. Nemám rád ani automatickou detekci istty(), kdy program vypisuje něco jiného na terminál a něco jiného do roury nebo přesměrování.

Protože všechny tyhle implicitnosti vedou k chybám. Triviální příklad. Pokud by někdo vylepšil roury o předávání informací, tak by se mohlo stát, že příkaz cat /dev/sda > /dev/null by se prostě nevykonal, protože by systém usoudil, že to nemá žádný výstup, tak nebude zatěžovat storage, cache apod. Ale někdo takto může kontrolovat stav storage a to, zda jdou přečíst všechny bloky. A takových nulových příkazů s netriviálním vlivem je víc.

K tomu terminálu, co dodat. Myslel jsem si, že ncurses to řeší kompletně. Přijde mi divné, že se dneska musí speciálně řešit věci jako stín pod menu, to uměl Turbo Pascal v roce 1990 v dosu. (V roce 1997 jsem psal tui rozhraní v pascalu, ale pravda, netuším, co všechno řešila ta knihovna a bylo to tehdy jen v dosu, dnešní rozmanitost terminálů je asi fak šílená.)
31.12.2019 16:55 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
netuším, co všechno řešila ta knihovna
Já bych si tipnul, že všechno. Jednou jsem si říkal, že když taková věc existovala už takhle od pradávna, napsat dneska něco v ncurses nemůže být tak těžké. Chtěl jsem napsat jednoduchý prográmek, kterým bych si ušetřil něco práce. Nakonec jsem si ji ušetřil tak, že jsem se na to po několika hodinách snažení vykašlal.
Quando omni flunkus moritati
Josef Kufner avatar 31.12.2019 17:02 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Ta knihovna jménem TurboVision například neřešila podporu dálnopisů z poloviny 20. století. Měla prostě IBM PC a MS DOS. To je celkem podstatné zjednodušení oproti ncurses a podpoře desítek let historie terminálů všech možných systémů. Dnes je opravdu nejlepší řešení se na to vykašlat a použít třeba Qt.
Hello world ! Segmentation fault (core dumped)
31.12.2019 17:15 trekker.dk | skóre: 71
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Akorát mi to na serveru v terminálu moc nepojede...
Quando omni flunkus moritati
xkucf03 avatar 31.12.2019 17:15 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Na stránce tvision.sourceforge.net píší:

This port is a port of the C++ version for the DOS, FreeBSD, Linux, QNX, Solaris and Win32 platforms.

To by teoreticky stálo za vyzkoušení.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 18:07 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Ten kód už několikrát umřel a několikrát byl oživen. Teď, co vím, tak je to zase mrtvé. Třeba "fp" "Free Pascal IDE" nad tím běží a vypadá to luxusně. Nicméně není to aktivně udržované a chybí tomu podpora unicode.

Hezký a živý projekt je např. finalcut https://github.com/gansm/finalcut
Heron avatar 31.12.2019 17:06 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
No já se do ncurses nikdy pořádně nepoložil, jednou jsem v tom chtěl něco napsat, čekal jsem (naivně), že bude stačit definovat kde chci mít "okýnka" pro textový výstup (v podstatě subterminály), kam bych posílal text a velice rychle jsem to vzdal. Napsal jsem si triviální prográmky, v tmuxu rozdělil plochu na 4 okna a v každém pustil jiný program a je to. Jednoduchý nástroj pro monitorování několika věcí. O to víc obdivuju lidi, co jsou schopni napsat třeba MC a nemyslel jsem si, že to je takový masakr.
xkucf03 avatar 31.12.2019 17:18 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Nezkoušel jsi termui nebo wtfutil?
Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 31.12.2019 17:23 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Nezkoušel. Já hlavně nejsem a nechci být programátor. Jsem admin a chci používat skvělé výtvory od ostatních. Nejlepší chvíle při vývoji nějakého skriptu jsou pro mě momenty, kdy najdu hotový modul a můžu smazat 500 řádků kódu a potom nejvíc, když najdu v repu jiný program řešící můj problém. To potom moje dílo okamžitě zahazuju a přecházím na program z repa.
xkucf03 avatar 1.1. 14:42 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Nemám rád ani automatickou detekci istty(), kdy program vypisuje něco jiného na terminál a něco jiného do roury nebo přesměrování.

Vím, že je to trochu ošemetné, ale někdy podle mého úprava chování dle toho, zda vstup/výstup je terminál, má smysl.

Co si třeba myslíš o programech, které při příliš dlouhém výstupu spustí jako podproces less a nasměrují výstup do něj, místo aby ti zahltily terminál?

Návrh b) v komentáři #65 je tomu hodně podobný.

Protože všechny tyhle implicitnosti vedou k chybám. Triviální příklad. Pokud by někdo vylepšil roury o předávání informací, tak by se mohlo stát, že příkaz cat /dev/sda > /dev/null by se prostě nevykonal, protože by systém usoudil, že to nemá žádný výstup, tak nebude zatěžovat storage, cache apod.

Např. pro localhost/loopback je v jádře nějaká zkratka a funguje to trochu jinak než komunikace s jinými adresami (byť na stejném počítači). Zkoušel jsem to hledat a nemůžu to najít, myslím, že o tom byla před pár lety zprávička. Nemáte někdo odkaz?

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
xkucf03 avatar 1.1. 14:46 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Možná tohle: net-tcp: TCP/IP stack bypass for loopback connections, ale spíš si myslím, že to byla nějaká novější změna než v roce 2012.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 1.1. 15:14 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Vím, že je to trochu ošemetné, ale někdy podle mého úprava chování dle toho, zda vstup/výstup je terminál, má smysl.
Jasně, já jsem to taky jednou použil pro program, jehož výstup jsem často strojově zpracovával a místo parametru mi přišlo jednodušší (na implementaci) istty, ale obecně to považuju za chybu návrhu. A úprava výstupního formátu tak, aby to bylo pěkné jak pro člověka, tak pro stroj, mi přišla příliš náročná. To už je fakt lepší udělat --export-csv a mít výstup pro člověka a stroj kompletně oddělený.
Co si třeba myslíš o programech, které při příliš dlouhém výstupu spustí jako podproces less a nasměrují výstup do něj, místo aby ti zahltily terminál?
Tohoto je plný freebsd a lezu z toho po zdi. Je tam nějaké dvě stě tisíc let staré more, neumí to barvy, neumí to hledat. Naštěstí | less zafunguje. Ale obecně ne, nemělo by se to dělat. To less si tam přidá každý, navíc tmux i screen umí vlastní scrooling a emulátor terminálu také. Prostředků na volitelný paging je dost a ne každému může ten použitý vyhovovat.
Návrh b) v komentáři #65 je tomu hodně podobný.
Nebrat. Pokud má nějaký program binární výstup a admin jej nechá vypsat na terminál, má se to vypsat na terminál (s tím, že ho to rozhodí a potom je poslepu nutné psát reset (neplést s reboot ;-))). Ještě je akceptovatelné, pokud se program zeptá, podobně jako less:
less pribeh.pdf 
"pribeh.pdf" may be a binary file.  See it anyway?
Automatický převod binárního výstupu na hezký textový výstup by mohl vést k chybám typu: * * * * * relpipe-in- >> /var/log/pretty.log, což jsem za svou praxi taky viděl několikrát. Program pracoval, úloha se spouštěla, ale log se plnil nesmyslama.
Např. pro localhost/loopback je v jádře nějaká zkratka a funguje to trochu jinak než komunikace s jinými adresami (byť na stejném počítači). Zkoušel jsem to hledat a nemůžu to najít, myslím, že o tom byla před pár lety zprávička. Nemáte někdo odkaz?
Na tohle je expert mikrotik. Některé packety některé chainy kompletně obcházejí, někdy se do fw nedostanou vůbec a mk to řeší přes ten switchovací čip apod.

Jasně, z důvodu výkonu to má smysl, ale je každopádně dobré to dobře zdokumentovat.

Jinak to mi připomnělo chování db klientů. Je rozdíl mezi localhost a 127.0.0.1. Takže někteří admini si nastaví fw, nastaví si grant apod a potom se tam "ani z lokálu" nejde připojit. Rozdíl je ten, že localhost se připojuje přes unix socket, zatímco 127.0.0.1 přes TCP socket (stejně jako každé jiné spojení po síti). Připojení přes UNIX socket je u PG výhodné, protože dokáže identifikovat uživatele klienta a připojit jej automaticky (pokud je to v pg_hba.conf povoleno). U 127.0.0.1 to "najednou" chce heslo.
xkucf03 avatar 1.1. 16:21 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Tohoto je plný freebsd a lezu z toho po zdi. Je tam nějaké dvě stě tisíc let staré more, neumí to barvy, neumí to hledat. … ne každému může ten použitý vyhovovat.

Od toho je proměnná $PAGER:

PAGER="more" hg log
PAGER="more" man man
PAGER="less" hg log
PAGER="less" man man

Někdo si tam nastavuje dokonce VIM… (PAGER="/usr/share/vim/vim80/macros/less.sh" nebo něco vlastního).

navíc tmux i screen umí vlastní scrooling a emulátor terminálu také

Třeba v Konsoli je myslím výchozí nastavení 1 000 řádků. Často zjistíš, že by sis měl nastavit víc, až ve chvíli, kdy o nějaký zajímavý výstup přijdeš. Ten less (ať už explicitní nebo automatický) má výhodu v tom, že data nezahodí, ani když jsou moc dlouhá.

Nebrat. Pokud má nějaký program binární výstup a admin jej nechá vypsat na terminál, má se to vypsat na terminál (s tím, že ho to rozhodí a potom je poslepu nutné psát reset (neplést s reboot ;-))).

Mně se do toho taky moc nechce. Uživatel by měl vědět, že výstupem relpipe-in-*relpipe-tr-* jsou binární strojově čitelná data určená k tomu, aby se zpracovávala nějakým dalším nástrojem. Tzn. nechci zatemňovat tu obecnou logiku zdroj-dat | transformace | výstupní-formátování. Ale možná přidám nějakou proměnnou prostředí, kterou když si uživatel nastaví, tak pak zafunguje ta automatika. Tzn. nebude to výchozí chování, ale když si o to uživatel výslovně řekně, tak to může mít.

Jinak to mi připomnělo chování db klientů. Je rozdíl mezi localhost a 127.0.0.1. Takže někteří admini si nastaví fw, nastaví si grant apod a potom se tam "ani z lokálu" nejde připojit. Rozdíl je ten, že localhost se připojuje přes unix socket, zatímco 127.0.0.1 přes TCP socket (stejně jako každé jiné spojení po síti). Připojení přes UNIX socket je u PG výhodné, protože dokáže identifikovat uživatele klienta a připojit jej automaticky (pokud je to v pg_hba.conf povoleno). U 127.0.0.1 to "najednou" chce heslo.

Na tohle už jsem taky někdy narazil a nelíbí se mi to. Je to takové upřednostnění pohodlnosti (slovo localhost si pamatuje každý, ale kolik lidí zná z hlavy cestu k patřičnému unixovému soketu?) před spolehlivostí a transparentností.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Heron avatar 1.1. 16:53 Heron | skóre: 52 | blog: root_at_heron | Olomouc
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Od toho je proměnná $PAGER:
Vím, tu nemám nastavenou. Ony to dělají jen některé programy jako portmaster a freebsd-update, u toho portmasteru to ani není jeho vina, ale děje se to i u make install v případě, kdy port chce sdělit nějaký text adminovi. Takže tato komponenta.
Často zjistíš, že by sis měl nastavit víc, až ve chvíli, kdy o nějaký zajímavý výstup přijdeš.

Tak výpisy by měly být idempotentní, takže si to můžeš nechat vypsat znovu do lessu. (Muhehe, toto je téma na flame, už to tady bylo jednou u doporučení spouštět dlouho běžící programy přes systemd-run a výpis číst v journalu :-D)
Ale možná přidám nějakou proměnnou prostředí, kterou když si uživatel nastaví, tak pak zafunguje ta automatika. Tzn. nebude to výchozí chování, ale když si o to uživatel výslovně řekně, tak to může mít.
Jo. Nebo parametr. Dával bych přednost parametru před env.
Josef Kufner avatar 2.1. 12:40 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Jo. Nebo parametr. Dával bych přednost parametru před env.
Spíš obojí. Parametr s nejvyšší prioritou, pak env, pak zakompilovaný default.

Tady je vhodné se inspirovat přepínači --color, které jsou docela dobře zavedené v mnoha programech.

A klidně bych udělal výchozí pager s formátováním. Pokud vynecháš výstupní formátování a pošleš to rovnou do terminálu, tak by se automaticky spustilo něco rozumného a less. Samozřejmě by o tom měl být odstaveček hned na začátku dokumentace a řádek v --help, aby se člověk nedivil, ale nějak mne nenapadá situace, kdy bych chtěl vypsat ten binární bordel do terminálu. Spíš mi přijde fajn, že by šlo psát tu kolonu postupně a neřešit už od začátku konec. Na druhou stranu, pokud si takový výstup někam přesměruju s tím, že si ho chci uložit, bude to trochu podivné, ale asi to za to stojí a jde to řešit drobným varováním na začátku automaticky formátovaného výpisu, které půjde vypnout.
Hello world ! Segmentation fault (core dumped)
xkucf03 avatar 31.12.2019 16:51 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Pokud bych měl v Unixu filtr, který dokáže agregovat a grupovat podle nějakých atributů, tak by bylo hezké abych mohl napsat "zdroj | sum(xx) groupby(yyy) | graph bar". Zdroj by dostal jiným kanálem informaci, že se po něm požadují atributy xxx, yyy. Tím by mohla odpadnout parametrizace zdroje i finálního konzumenta (protože ten by jiným kanálem dostal metadata).

V objektovém (případně funkcionálním) světě by tohle šlo řešit pomocí líného vyhodnocování. I když pořád by to vlastně byl full table scan, jen s tím, že by se některé hodnoty nemusely načítat (nebo ty dynamické vypočítávat), ale nepodporovalo by to indexy. To posílání predikátu vzdálenému/cizímu zdroji je zajímavější a vlastně jsem se s tím už párkrát setkal (posílal se popis filtru a z něj se na druhé straně generoval dotaz do LDAPu nebo relační databáze). Ale asi to moc nepatří do operačního systému a vede to na poměrně složitá rozhraní1, která patří spíš na úroveň aplikací nebo nějakého middlewaru. Asi by to musel být nějaký OS, který s tímhle počítá už od začátku.

[1] když to srovnám se složitostí unixových/posixových C API, tak mi to tam vyloženě nesedí

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 17:49 okbobcz
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Dnes jsou roury spíš mechanismus "push|pull", kdy konzument a zdroj o sobě neví. Kdežto ty "inteligentnější" roury by mohly být "pull" nebo "push". Konzument by si mohl říct zdroji, že chce data a jaká data chce. A zdroj by mu je dal, pokud by je měl. Nemyslím si, že by to vyžadovalo extra složité rozhraní - docela dobře si dovedu představit nějaký jednoduchý dotazovací jazyk - "FROM ZDROJ READ atttr1, attr2 WHERE attr3=xxx", nebo SQL, to už je jedno.

POSIX API je jednoduché - ale pokrývá v podstatě jen základní operace. Už i docela jednoduché záležitosti jako získání seznamu uživatelů se musí doprogramovat - musím načíst soubor, ten naparsovat, a pak mohu pracovat s výsledkem. Kdybych měl k dispozici chytřejší zdroj se seznamem uživatelů, tak je jen otevřu a budu rovnou načítat strukturovaná data.

Představte si, že všechny konfiguráky, které máte dnes v různých formátech by byly uložené v CSV, a měl bych knihovnu, která by mi umožnila s nimi pracovat podobně jako třeba pracuji s SQLite. Nemusel bych každý soubor extra parsovat - prostě bych si otevřel zdroj, a pak jej třeba sekvenčně přečetl nebo třeba použil SQL. Jsem na vyšší úrovni než je jen práce se s textovým souborem, ale pořád stále nízko. V podstatě jediné, co bych nedělal je to ruční parsování.
31.12.2019 14:36 QED
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
jak je vše přeplácané, překomplikované, jak chybí jednotící koncepty
| relpipe-in-cli generate-from-stdin relation_from_stdin 3

\ a integer

\ b string

\ c boolean

Takže tohle je lepší?
xkucf03 avatar 31.12.2019 15:21 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Tohle je jeden z nejstarších modulů a jeho syntaxe se bude měnit, aby byl v souladu s ostatními příkazy a taky nebudeš muset psát tu 3 (počet atributů).

Ale bez ohledu na to:

Takže tohle je lepší?

Lepší než co? Tenhle příkaz převádí data (oddělená nulovým bajtem čtená ze standardního vstupu) na relaci. Těžko vymyslíš něco jednoduššího, vzhledem k tomu, že:

  • Jestliže názvy atributů ve vstupních datech chybí, je potřeba je zadat jako parametr tomuto příkazu.
  • Stejně tak když chybí datové typy – taky je potřeba je zadat zde (to bude později volitelné a výchozí typ bude string)
  • Počet atributů neznáš → opět je potřeba ho zadat. Ať už takto explicitně číslem, nebo syntaxí parametrů.
  • Nelze vycházet z počtu parametrů, protože pomocí nich lze zadávat i data (část dat může být formou parametrů a část se může načíst ze standardního vstupu).

Ve výsledku to bude vypadat asi nějak takto:

relpipe-in-cli --relation "relation_from_stdin" --attribute "a" "integer" --attribute "b" "string" --attribute "c" "boolean"

případně:

relpipe-in-cli --relation "relation_from_stdin" --attribute "a" --type "integer" --attribute "b" --type "string" --attribute "c" --type "boolean"

s tím, že bys mohl typy nechat výchozí:

relpipe-in-cli --relation "relation_from_stdin" --attribute "a" --attribute "b" --attribute "c"

n.b. názvy atributů jsou libovolné řetězce, které můžou klidně začínat znaky "--".

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Bedňa avatar 1.1. 20:34 Bedňa | skóre: 34 | blog: Žumpa | Horňany
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
A jak bys jinak řešil převod stromu na relace? Tohle je ještě dost přívětivé – jedním XPath výrazem vybereš záznamy a dalšími XPath dotazy vybereš atributy. Tohle nelze namapovat nějak automaticky – některé atributy (relační) hledáš v elementech, některé v atributech (XML), některé někde hlouběji v potomcích, jiné zase v nadřazených uzlech. Ostatně totéž se používá v databázích a i se to i stejně jmenuje.
Nerobil som úplné riešenie, pretože nejaký automat nad XML je vôbec problém napísať. Páč nad:
<clovek>
    <meno>
        Franta
    </meno>
    <sex>
        man
    </sex>
</clovek>
Je ten parser jednoduchý.

Ale proste XML je ideálny formát ako dáta prasiť a to vo večšine XML je:
<clovek>
    <meno>
        Franta
    </meno>
    <prasime attribute="sex" value="man">
    </prasime>
</clovek>
Toto proste nemá logické riešenie.
protože ten záznam je zapsaný na více řádcích. Šlo by to nějak v AWKu ...
(G)AWK vie práve spracovávať hocijaký vstup, mno zrejme to neskončí s nejakoým triviálnym zápisom.
Největší problém je, že to přichází s asi dvaceti- nebo třicetiletým zpožděním.
Mno keď to bude viac ľudskejšie ako som písal, je úplne jedno kedy to príde, nežijeme v minulosti ale teraz :)
KERNEL ULTRAS video channel >>>
xkucf03 avatar 1.1. 21:06 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Toto proste nemá logické riešenie.

Proto existuje XPath, se kterým je to řešitelné snadno:

<lide>
        <clovek>
                <meno>
                        Franta
                </meno>
                <prasime attribute="sex" value="man">
                </prasime>
                <prasime attribute="city" value="Praha">
                </prasime>
        </clovek>
<clovek>
                <meno>
                        Winona
                </meno>
                <prasime attribute="sex" value="woman">
                </prasime>
                <prasime attribute="born" value="1971">
                </prasime>
        </clovek>
</lide>

Skript:

cat lide.xml \
    | relpipe-in-xmltable \
        --relation lide \
            --records '/lide/clovek' \
            --attribute 'name' string 'normalize-space(meno)' \
            --attribute 'sex'  string 'prasime[@attribute="sex"]/@value' \
            --attribute 'city' string 'prasime[@attribute="city"]/@value' \
            --attribute 'born' string 'prasime[@attribute="born"]/@value' \
    | relpipe-out-tabular

Výsledek:

lide:
 ╭───────────────┬──────────────┬───────────────┬───────────────╮
 │ name (string) │ sex (string) │ city (string) │ born (string) │
 ├───────────────┼──────────────┼───────────────┼───────────────┤
 │ Franta        │ man          │ Praha         │               │
 │ Winona        │ woman        │               │ 1971          │
 ╰───────────────┴──────────────┴───────────────┴───────────────╯
Record count: 2

Mimochodem, totéž můžeš dělat v databázích (např. PostgreSQL), kde je funkce xmlTable(), kterou je ten relpipe-in-xmltable inspirovaný (tzn. opět se snažím nevynalézat kolo a raději použít řešení, které se už osvědčilo jinde).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Bedňa avatar 1.1. 22:14 Bedňa | skóre: 34 | blog: Žumpa | Horňany
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Takto to vyzerá OK, ale,

Keby si to dokázal vycucať bez toho zložitého zápisu tak by to bolo na tlieskanie.

Ja viem, že to nie je zrovna jednoduchá úloha, ale nejaká voľba "--try" by si mohla typnúť že niektoré dáta sú v "TAG" a niektoré v "attribute".

KERNEL ULTRAS video channel >>>
Josef Kufner avatar 2.1. 12:47 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Na slušnější XML by asi šlo udělat automatiku, která by vzala první potomky jako řádky tabulky a druhé jako sloupečky. Nejlépe tu detekci řádků a sloupečků oddělit, aby se dalo říct, odkud z XML vytáhnout tu tabulku. Pak by také mohlo jít použít placeholder pro sloupečky, např:
--attributes 'prasime[@attribute="%%"]/@value'
Něco jako matchování regexpem, ale v XPath. (Což asi bude docela oříšek implementovat.)
Hello world ! Segmentation fault (core dumped)
xkucf03 avatar 2.1. 12:59 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

… a ve výsledku to bude složitější a méně přehledné, než tam těch pár atributů vyjmenovat explicitně a říct počítači přesně, co chceš, a ne ho nechat hádat.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Josef Kufner avatar 2.1. 13:53 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
To záleží na tom, co chceš dělat a jak to chceš používat.
Hello world ! Segmentation fault (core dumped)
xkucf03 avatar 2.1. 14:44 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Dobře, trochu to rozvedu.

Na slušnější XML by asi šlo udělat automatiku, která by vzala první potomky jako řádky tabulky a druhé jako sloupečky.

XML popisuje stromovou strukturu, jeho přirozený datový model je strom uzlů. Pokud se ti to nedaří (snadno) napasovat na relaci (nebo jinou datovou strukturu či model), neznamená to, že by to XML bylo neslušné.

A už vůbec nemůžeš čekat, že to XML bude ve tvaru:

<tabulka>
    <řádek>
        <sloupec1>hodnota1</sloupec1>
        <sloupec2>hodnota2</sloupec2>
        <sloupec3>hodnota3</sloupec3>
    </řádek>
    <řádek>
        …
    </řádek>
</tabulka>

tzn. že ty řádky budou hned v první úrovni pod kořenovým elementem. Běžně můžou být zanořené hlouběji. A i když jde dané XML logicky namapovat na několik relací, neznamená to, že to bude takhle přímočaré. Některé atributy (relační) se můžou brát z rodičovských elementů nebo hledat někde hlouběji atd. To je normální zdravé XML.

Ten relační pohled na XML je fajn, protože často stačí a dá se to namapovat. A nebo někdy potřebuješ jen podmnožinu původních dat, kterou dokážeš namapovat. Tam vidím potenciál xmlTable(). Kromě toho jsou i případy, kdy to rozumně namapovat nejde a ty relace v tom prostě (z logického pohledu) nejsou. A pak nemá cenu to znásilňovat a je lepší použít třeba to XQuery.

automatiku, která by vzala první potomky jako řádky tabulky a druhé jako sloupečky

Dovedu si představit nějakou heuristiku, která by v XML hledala opakující se struktury a ty pak prohlásila za záznamy jednotlivých relací. A k nim by bylo nutné připojit i hodnoty z elementů a atributů nadřazených uzlů jako např. user="root" nebo context="default" z příkladu v blogu.

Tohle by mi dávalo smysl v rámci nějakého interaktivního průvodce pro import dat, který by ti navrhl mapování, ty by sis ho zkontroloval a převedl data. Výstupem by mohly být i parametry pro funkci xmlTable(), takže bys to mohl používat opakovaně.

Ale určitě bych nechtěl, aby to takhle automagicky fungovalo v rámci nějakého příkazu/skriptu, na který uživatel nedohlíží a nemá ho vždy pod kontrolou. Pak se totiž stane, že v XML třeba přibudou nové elementy a automatika najednou detekuje jiné relace než minule. Nebo autor nástroje vylepší heuristický algoritmus, což bude dávat sice lepší, ale jiné, výsledky a původní skript, se rozpadne.

Tohle je přesně způsob uvažování, který nemám rád – na první pohled se tváří, že věci zjednodušuje a šetří práci, ale ve skutečnosti zavádí skrytou komplexitu a snižuje spolehlivost systému. Ten je potom křehký a funguje nepředvídatelně. A takových případů je v dnešním softwaru bohužel hodně – jsou to časované bomby, které nečekaně bouchnou a rozbijí to, co dříve fungovalo.

Pak by také mohlo jít použít placeholder pro sloupečky, např: …˙Něco jako matchování regexpem, ale v XPath. (Což asi bude docela oříšek implementovat.)

Regulární výrazy v Relačních rourách používám docela dost. Tohle by nebylo tak těžké implementovat, prostě bys zadal jen jeden XPath v --records a místo dalších XPath výrazů v --attribute bys zadal jen regulární výraz, který by hledal přímé potomky1 (elementy a atributy) v elementech nalezených pomocí --records a mapoval je na relační atributy stejného názvu. Potíž je v tom, že struktura relace je odvozená od vstupních dat. Takže pokud v XML budou některé hodnoty chybět, relace bude mít najednou méně atributů (místo aby byly jen prázdné). A u té automatiky ti můžou zmizet dokonce celé relace, pokud v XML na vstupu zrovna dané uzly nebodu.

[1] podle názvu – akorát tím regulárním výrazem nedokážeš popsat jmenné prostory, takže je to hodně omezené

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Josef Kufner avatar 2.1. 15:19 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Já se jakékoliv heuristice zcela záměrně v tom návrhu vyhnul právě z těch důvodů, které popisuješ. Nechci tam žádnou magii, ale pár jednoduchých pravidel, které si dobře poradí s jednoduchými ale častými případy, například takové RSS nebo HTML tabulky.

Použít názvy tagů potomků je deterministické, na jmenné prostory si stačí definovat svoje aliasy a namapovat to na aliasy použité v XML.

Navíc taková šikovná pravidla můžeš zapínat nějakým parametrem, takže to nebude magické. Nejlépe s tím, aby to defaultně bez parametrů použilo nějaké jednoduché hezké pravidlo, které ukáže, že to něco dělá. Například jako když find spustíš bez parametrů a on prostě najde všechno v aktuální cestě, tak by se mohlo XML interpretovat tak, že kořenový element je rodič seznamu a elementy jednotlivých položek jsou atributy. Když uvedeš jiného rodiče seznamu, tak se použije namísto defaultu, když vyjmenuješ atributy, tak se nepoužijí všechny potomci automaticky. Jednoduché, předvídatelné a funkce jsou snadno objevitelné, protože uživatel nezačíná na zelené louce, ale má hned něco, od čeho se odpíchne.
Hello world ! Segmentation fault (core dumped)
30.12.2019 22:33 Tomáš
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
A já se tak těšil, že naparsuje XML regulárním výrazem. No nic, třeba příště.
Martin Tůma avatar 30.12.2019 23:27 Martin Tůma | skóre: 38 | blog: RTFM | Praha
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Obávám se, že na toto je i "sane software manifesto" krátký...
Každý má právo na můj názor!
xkucf03 avatar 30.12.2019 23:52 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

O to jsem se naštěstí nikdy nepokoušel (což nás asi naučil Kosek ve škole, že tudy cesta nevede).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
Josef Kufner avatar 31.12.2019 13:54 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Mimochodem, jak to dopadne, když se ten relpipe formát pošle jen tak do terminálu? Je to nějak přiměřeně čitelné i v neformátovaném tvaru, nebo to totálně rozdrbe terminál?
Hello world ! Segmentation fault (core dumped)
xkucf03 avatar 31.12.2019 15:04 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Je to binární formát, který má být úsporný, není cílem ho nějak optimalizovat pro čitelnost člověkem nebo „nerozdrbání“ terminálového výstupu. Od toho jsou výstupní filtry.

Nad čím jsem ale uvažoval:

a) Dát na začátek nějaké jedinečné magické číslo (což asi udělám tak jako tak). A pak by šlo napsat rozšíření do terminálu, které když odchytí tuhle posloupnost bajtů, tak data nějak uživatelsky přívětivě vykreslí (případně by to mohlo být i nějak interaktivní, nabídnout to různé formáty nebo vykopírování/odeslání dat jinam). Ale to by byla spíš taková specialita pro někoho, kdo to používá hodně a není to pro něj obecný emulátor terminálu ale spíš jakési rozhraní pro práci s daty (něco jako RKWard GUI pro R). Ostatně stejně tak by nějaký specializovaný terminál mohl třeba vykreslovat bitmapové nebo vektorové obrázky, když přijdou ze standardního výstupu nějakého příkazu.

b) Příkazy, které generují relační data (relpipe-in-*relpipe-tr-*) by se mohly podívat, jestli je STDOUT terminál a pokud je, tak by spustily podproces relpipe-out-tabular (případně jiný, třeba na základě proměnné prostředí), jeho výstup napojily na STDOUT a na jeho vstup poslaly relační data (která měla jít původně na STDOUT).

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 15:30 sigma
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
b) Příkazy, které generují relační data (relpipe-in-* a relpipe-tr-*) by se mohly podívat, jestli je STDOUT terminál a pokud je, ...
Možná jedna z věcí, co obecně chybí, je lepší možnost obousměrné signalizace na rouře než prosté isatty(). Např. aby mohla konzumující strana roury signalizovat podporované/preferované formáty dat straně generující. Nebo i v dopředném směru předat volitelně nějaká další metadata. Tohle by šlo udělat plně zpětně kompatibilní, ale asi ta potřeba není nějak silná.
xkucf03 avatar 31.12.2019 15:46 xkucf03 | skóre: 48 | blog: xkucf03
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML

Ano, tohle by bylo zajímavé vylepšení. V podstatě by stačilo procesům na FD 0, 1 a 2 nastavit místo rour sokety. Pak by se proces podíval, jestli je to roura, terminál nebo soket. A v případě soketu by mohl do STDIN i zapisovat (a poslat tam třeba ty podporované formáty). Akorát tam bude trochu jinak fungovat zavírání.

A taky by bylo potřeba definovat, kdo má kdy komunikovat, aby se to nezaseklo na tom, že oba procesy čekají, co řekne druhá strana (např. když v „protisměru“ nepřijde ten seznam podporovaných formátů). Nebo tam mít nějakou signalizaci formou systémových volání nebo knihovních funkcí, které to nějak propojí bokem.

Asi bys potřeboval vědět, jestli daný program toto rozšíření podporuje, ještě než zavoláš exec() a spustíš ho.

IMHO to je něco, co vypadá na první pohled jednoduše, ale když to začneš implementovat, tak zjistíš, že to triviální není.

Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
31.12.2019 16:19 jiwopene | skóre: 19
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
Já bych si to představoval takhle:
  1. Pokud je na výstupu termnál, který chápe relpipes, pošle se escape sekvence, pak binární data (a na konci výstupu zase escape sekvence oznamující konec). Jako to dělá Terminologytycat.
  2. Pokud je na výstupu jiný terminál, použije se rovnou relpipe-out-tabular.
  3. Pokud je na výstupu program, který chápe binární data (jiný program relpipe-*), pošlou se binární data tak, jak jsou.
  4. Ve všech ostatních případech (program nejspíš nechápe binární data z relpipes) by se dal použít nějaký textový protokol (např. JSON, XML, …), takže by se data dala uložit do souboru a snadno později editovat nebo poslat dál.
U bodu 1 bych „detekci“ podpory řešil asi proměnnou prostředí (např. terminál nastaví shellu RELPIPES_TTY=1). Bod 4 by se hodil při logování dat (můžu prohlížet i na počítači, kde nemám nainstalované relpipes), ale je to spíš jen takový divný nápad. Asi by bylo lepší to nechat jako samostatný program.
.sig virus 3.2_cz: Prosím, okopírujte tento text do vaší patičky.
Josef Kufner avatar 31.12.2019 16:42 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
To je příliš komplikované. Terminology je dobrý příklad, ale řešit různé formáty pro různě napojené roury bude peklo. Vem si jen takový jednoduchý příklad, kdy chceš obrázek prohnat filtrem a uložit do souboru. Než tomu filtru vyladíš parametry, necháš si pár pokusů ho vykreslovat a když je hotovo, jen to přesměruješ do souboru. Pak na uložený soubor koukneš a ono to je rozbité, neboť tam je nějaký metadatový bordel navíc.
Hello world ! Segmentation fault (core dumped)
Josef Kufner avatar 31.12.2019 16:53 Josef Kufner | skóre: 69
Rozbalit Rozbalit vše Re: Používáme AWK pro filtrování XML
A jsi si jist, že jistá úroveň terminálové přátelskosti není žádoucí?

Stačilo by, aby ten binární formát obsahoval občas ten správný znak, aby to trochu vypadalo. Třeba schovat '\n' na konci záznamu a hned to bude alespoň na řádky nalámané.
Hello world ! Segmentation fault (core dumped)

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.