Raspberry Pi Connect, tj. oficiální služba Raspberry Pi pro vzdálený přístup k jednodeskovým počítačům Raspberry Pi z webového prohlížeče, byla vydána v nové verzi 2.5. Nejedná se už o beta verzi.
Google zveřejnil seznam 1272 projektů (vývojářů) od 185 organizací přijatých do letošního, již jednadvacátého, Google Summer of Code. Plánovaným vylepšením v grafických a multimediálních aplikacích se věnuje článek na Libre Arts.
Byla vydána (𝕏) dubnová aktualizace aneb nová verze 1.100 editoru zdrojových kódů Visual Studio Code (Wikipedie). Přehled novinek i s náhledy a videi v poznámkách k vydání. Ve verzi 1.100 vyjde také VSCodium, tj. komunitní sestavení Visual Studia Code bez telemetrie a licenčních podmínek Microsoftu.
Open source platforma Home Assistant (Demo, GitHub, Wikipedie) pro monitorování a řízení inteligentní domácnosti byla vydána v nové verzi 2025.5.
OpenSearch (Wikipedie) byl vydán ve verzi 3.0. Podrobnosti v poznámkách k vydání. Jedná se o fork projektů Elasticsearch a Kibana.
PyXL je koncept procesora, ktorý dokáže priamo spúštat Python kód bez nutnosti prekladu ci Micropythonu. Podľa testov autora je pri 100 MHz približne 30x rýchlejší pri riadeni GPIO nez Micropython na Pyboard taktovanej na 168 MHz.
Grafana (Wikipedie), tj. open source nástroj pro vizualizaci různých metrik a s ní související dotazování, upozorňování a lepší porozumění, byla vydána ve verzi 12.0. Přehled novinek v aktualizované dokumentaci.
Raspberry Pi OS, oficiální operační systém pro Raspberry Pi, byl vydán v nové verzi 2025-05-06. Přehled novinek v příspěvku na blogu Raspberry Pi a poznámkách k vydání. Pravděpodobně se jedná o poslední verzi postavenou na Debianu 12 Bookworm. Následující verze by již měla být postavena na Debianu 13 Trixie.
Richard Stallman dnes v Liberci přednáší o svobodném softwaru a svobodě v digitální společnosti. Od 16:30 v aule budovy G na Technické univerzitě v Liberci. V anglickém jazyce s automaticky generovanými českými titulky. Vstup je zdarma i pro širokou veřejnost.
sudo-rs, tj. sudo a su přepsáné do programovacího jazyka Rust, nahradí v Ubuntu 25.10 klasické sudo. V plánu je také přechod od klasických coreutils k uutils coreutils napsaných v Rustu.
tr -td -td -td tr -td -td -td --input --@onclickPřičemž těch řádků je hodně a některé (jako ten první) nenesou žádnou informaci. Ty podstatné řádky mají v poslední buňce input a potřeboval bych znát hodnotu textu v prvních dvou buňkách a parametr onclick elementu input v poslední buňce. Jak na to jít? Napadly mě dvě cesty jak toho dosáhnout: - sed: vymyslet regulární výraz, který z HTML vytáhne zajímavé HTML řádky (každý na jeden plaintext řádek) a pak pomocí prostého s/regexp/\1;\2;\3/ z těchto řádků vytáhnout řetězce a poskládat je. Vůbec ale netuším, vytáhnout ty podstatné HTML řádky - xsltproc --html: Zkusil jsem si vytvořit xsl styl, který tyto informace vytáhne. Nedaří se mi ale vytvořit šablonu tak, abych dostal obsah pouze ze mnou žádaných uzlů, buď se nevypíše nic nebo se vypíše obsah všech textových uzlů. Díky za jakoukoliv pomoc.
Jakmile z toho dostanu jeden HTML řádek na jeden plaintext řádek, tak jsem za vodou
A co třeba:
sed 's#</tr>#</tr>\n#' | sed -n '/<tr>/p' | \ sed 's#<tr><td>\([^<]*\)</td>...<input onclick="\([^"]*\)">...#\1 ..#'
's#</tr>#</tr>\n#'
=> 's#</tr>#</tr>\n#g'
PS: je to jenom nástřel, možná je to úplně špatně (a nakonec bude to XSLT nejlepším řešením)
--html The input document is an HTML file.
text/html
, ve skutečnosti není HTML.
Ještě je tady alternativa někde na pomezí - pokud umíte v AWK, tak bude možná nejrychlejší použít xgawk, což AWK upravený pro zpracování XML (místo řádkových vzorů se používá vzor pro počáteční elementy atp.) - více v dokumentaci.
sed
em, jak už jsem psal...
[html] [head] [title]titulek[/title] [script language="javascript"] skript, ktery obsahuje ruzne [elementy /] a mate tim xsltproc [/script] [head] [body] [table] [!-- layout --] [tbody] [tr] [td] [div] [table] [script language="javascript"]dalsi skript[/script] [tbody] [tr] [td]nadpis sloupce 1[/td] [td]nadpis sloupce 2[/td] [td]nadpis sloupce 3[/td] [td]nadpis sloupce 4[/td] [td][/td] [/tr] [tr] [td]text11[/td] [td]text12[/td] [td]text13[/td] [td]text14[/td] [td][input onclick="akce1"][/td] [/tr] [tr] [td]text21[/td] [td]text22[/td] [td]text23[/td] [td]text24[/td] [td][input onclick="akce2"][/td] [/tr][/tbody][/table][/div][/td][/tr][/tbody][/table][/body]přičemž celé <body> je na jednom řádku a potřebuji z toho dostat takovéto .csv:
text11;text12;akce1 text21;text22;akce2
Nejdřív bych naházel každý tag na jeden řádek (teda ukončit řádku za uzavíracím):
sed 's#</[^>]*>#&\n#g'
Tohle by mohlo dát všechny [tr]
do jednoho řádku a vytisknout je:
sed -n '/<tr>/{:a;s#</tr>#t k;N;s#\n##;b a;:k;p}'
Možná to nebude fungovat úplně přesně, ale myšlenka (použít N
a podmíněný skok t
) je snad správná.
Pak by mělo stačit prohnat to grep
em a sed
em přetransformovat...
user@stroj:~$ w3m tabulky.htm | awk '{...}'Taky mi z toho není jasné, jestli se v tom inputu objevují nějaké hodnoty generované javascriptem atp. To s ukázkou kódu nasimuluji stěží..
awk ' $0 ~ "[tr]" { ln = 0; } $0 ~ "[td]" { line[ln++] = $0; } $0 ~ "[/tr]" { print line[0] line[1] line[2] line[3] line[4]; } ' < file.html | sed 's/.../\1 \2 \3 \4 \5/'Ten sed už zvládneš určitě sám...
#!/usr/bin/env perl use strict; use warnings; undef $/; $_ = <>; my @ctx = m{ <tr>\s* # Úvodní TR <td>([^<]*)</td>\s* # První buňka <td>([^<]*)</td>\s* # Druhá buňka (?:<td>[^<]*</td>\s*)* # Zbývající buňky <td><input\s*onclick="(.*?)"> # INPUT, od kterého se odpíchneme (?{print "$1;$2;$3\n"}) # Vypsat výstup }gsx;Na zadané ukázce frčí dobře:
zoul@naima:~$ ./tabulky.pl < vstup.html text11;text12;akce1 text21;text22;akce2 zoul@naima:~$
<tr[^>]*>([^<]*)</td>\s* # První buňka?
#!/usr/bin/env perl -w0n my @ctx = m{ <tr[^>]*>\s* <td[^>]*>([^<]*)</td>\s* <td[^>]*>([^<]*)</td>\s* (?:<td[^>]*>[^<]*</td>\s*)* <td[^>]*><input\s*onclick="(.*?)"> (?{print "$1;$2;$3\n"}) }gsx;Byl bych řekl, že místo těžkopádného
[^>]*
(cokoliv kromě znaku >) bude fungovat i skromné srovnávání (.*?
), ale to mi z nějakého důvodu nešlo.
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:template match="/html/body/table/tbody/tr/td/div/table/tbody/tr[td[last()]/input]"> <xsl:value-of select="td[1]"/>;<xsl:value-of select="td[2]"/>;<xsl:value-of select="td[last()]/input/@onclick"/> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="*"><xsl:apply-templates select="*" /></xsl:template> </xsl:stylesheet>
creating dictionary for stylesheet reusing dictionary from opory.xsl for stylesheet xsltParseStylesheetProcess : found stylesheet xsltPrecomputeStylesheet: removing ignorable blank node xsltParseTemplateContent: removing text xsltCompilePattern : parsing '/html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input]' xsltCompilePattern : parsed /html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input], default priority 0.500000 added pattern : '/html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input]' priority 0.500000 xsltCompilePattern : parsing '*' xsltCompilePattern : parsed *, default priority -0.500000 added pattern : '*' priority -0.500000 parsed 2 templates Resolving attribute sets references Creating sub-dictionary from stylesheet for transformation Registered 0 modules reusing transformation dict for output Registering global variables Registering global variables from opory.xsl xsltProcessOneNode: no template found for / xsltProcessOneNode: applying template '*' for html xsltApplyTemplates: node: 'html' xsltApplyTemplates: select * xsltApplyTemplates: list of 2 nodes (...) xsltProcessOneNode: applying template '*' for tr xsltApplyTemplates: node: 'tr' xsltApplyTemplates: select * xsltApplyTemplates: list of 6 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 1 nodes xsltProcessOneNode: applying template '*' for input xsltApplyTemplates: node: 'input' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodesa v podobném duchu pokračuje dalších ~ 17k řádků.
/html/body/table/tbody/tr/td/div/tabletak, aby se chytil na tu správnou tabulku. Pokud v tom html jsou nějaká id, je nejlepší se chytit na ně. Jinak je potřeba zvolit správné pořadí elementů. Pokud ty tagy
<input>
jinde na stránce nejsou, můžete taky zkusit /html/body//table/tbody/tr[td[last()]/input]
/html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input]a výsledek jsem posílal minule.
Pokud v tom html jsou nějaká id, je nejlepší se chytit na ně.Vnější div má id "
p_r_i_n_t
". Zkusil jsem vztáhnout xpath výraz od něj:
id('p_r_i_n_t')/div/table/tbody/tr[td[last()]/input]a výsledek se od předchozího nijak neliší: Celé XML sem nechci posílat, tak dávám alespoň odkaz na zastřelenou obrazovku DOM inspektoru.
//div[@id='p_r_i_n_t']/div/table/tbody/tr[td[last()]/input]A podívejte se, jak jsou tagy zapsané v tom očištěném (XHTML) souboru, zda jsou malými písmeny, resp. přizpůsobte velikost písmen v XPath. Případně sem pošlete (nebo někam vystavte, přinejhorším pošlete e-mailem) alespoň začátek to XML – aby tam byl alespň jeden řádek s daty. Ta data a texty klidně nahraďte něčím jiným.
<div id='p_r_i_n_t'> <div align='center'> <h2>nadpis 2</h2> <p>lorem ipsum ...</p> <table border='1'> <tr> <th>nadpis 1</th> <th>nadpis 2</th> <th>nadpis 3</th> <th>nadpis 4</th> <th>nadpis 5</th> <th>nadpis 6</th> </tr> <tr bgcolor=""> <td>text11</td> <td>text12</td> <td>text13</td> <td align='right'>text14</td> <td align='right'>text15</td> <td><input type='button' value='Otevřít' onclick= 'js_fce("id")' /></td> </tr> <tr bgcolor="#FFCCCC"> <td>text21</td> <td>text22</td> <td>text23</td> <td align='right'>text24</td> <td align='right'>text25</td> <td><input type='button' value='Otevřít' onclick= 'js_fce("id")' /></td> </tr> (...) </table> </div> </div>Xpath výraz jsem podle toho upravil takto:
//div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input]a xsltproc si stále mele svou:
creating dictionary for stylesheet reusing dictionary from opory.xsl for stylesheet xsltParseStylesheetProcess : found stylesheet xsltPrecomputeStylesheet: removing ignorable blank node xsltParseTemplateContent: removing text xsltCompilePattern : parsing '//div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input]' xsltCompilePattern : parsed //div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input], default priority 0.500000 added pattern : '//div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input]' priority 0.500000 xsltCompilePattern : parsing '*' xsltCompilePattern : parsed *, default priority -0.500000 added pattern : '*' priority -0.500000 parsed 2 templates Resolving attribute sets references Creating sub-dictionary from stylesheet for transformation Registered 0 modules reusing transformation dict for output Registering global variables Registering global variables from opory.xsl xsltProcessOneNode: no template found for / xsltProcessOneNode: applying template '*' for html xsltApplyTemplates: node: 'html' xsltApplyTemplates: select * xsltApplyTemplates: list of 2 nodes (...) xsltProcessOneNode: applying template '*' for div xsltApplyTemplates: node: 'div' xsltApplyTemplates: select * xsltApplyTemplates: list of 1 nodes xsltProcessOneNode: applying template '*' for div xsltApplyTemplates: node: 'div' xsltApplyTemplates: select * xsltApplyTemplates: list of 3 nodes xsltProcessOneNode: applying template '*' for h2 xsltApplyTemplates: node: 'h2' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for p xsltApplyTemplates: node: 'p' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for table xsltApplyTemplates: node: 'table' xsltApplyTemplates: select * xsltApplyTemplates: list of 531 nodes (radek s nadpisy) xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 1 nodes xsltProcessOneNode: applying template '*' for input xsltApplyTemplates: node: 'input' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="tr[td[last()]/input]"> <xsl:value-of
select="td[1]"/>;<xsl:value-of select="td[2]"/>;<xsl:value-of
select="td[last()]/input/@onclick"/> <xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="//div[@id='p_r_i_n_t']/div/table"/>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:template match="tr[td[last()]/input]"><xsl:value-of select="td[1]"/>;<xsl:value-of select="td[2]"/>;<xsl:value-of select="td[last()]/input/@onclick"/><xsl:text> </xsl:text> </xsl:template> <xsl:template match="/"> <xsl:apply-templates select="//div[@id='p_r_i_n_t']/div/table"/> </xsl:template> <xsl:template match="*"><xsl:apply-templates select="*" /></xsl:template> </xsl:stylesheet>
<div>
níže, transformace funguje, ale pokud mu podstrčím celé html, tak se mu nechce. Mimochodem umí XSL vyříznout z onoho <input onclick='jsFunkce("číselné_ID")'/>
; ono číselné_ID
?
<html>
jmenný prostor? Ale to by snad xsltproc
něco zahlásil…
Pokud je jsFunkce("…")
(to okolo) vždy stejné, dalo by se použít funkcí substring
a string-length
, případně replace
. Např.
<xsl:value-of select="replace(td[last()]/input/@onclick,'jsFunkce\("(.*)"\)','$1')"/>
<html xmlns="http://www.w3.org/1999/xhtml">
Pokud jeJe. Takto to vypadá dobře, jestli to bude funkční uvidíme až po vyřešení toho namespace.jsFunkce("…")
(to okolo) vždy stejné, dalo by se použít funkcísubstring
astring-length
, případněreplace
.
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0"> …
sed -e 's/\ / /g;s/<html[^>]*>/<html>/;s/jsFunkce(\"\([^"]*\)\")/\1/;'Díky všem za čas a pomoc.
Nicméně DOM inspektor pěkně kecá, protože žádný tag tbody v původním ani očištěném html není!No jo, na tenhle oblíbený trik jsem zapomněl. On zobrazuje skutečný aktuální DOM dokumentu, tj. to co vznikne parsováním a „hádáním“ toho, jak ten dokument má správně vypadat.
xsltproc
v tom ukecaném výstupu zmínilo.
Tiskni
Sdílej: