Page 2 sur 4
Re: [script] Les news dans le terminal (résolu)
Publié : jeu. 17 juil. 2014, 22:15
par avi3000
benjarobin a écrit :Elle est peut être légèrement plus simple, mais ne fait même pas 1% de l'autre...
Excellente contribution, éminemment constructive.
Il me semblait que le formatage multi-lignes, qu'il soit fait en sed ou awk, représentait 99% de l'intérêt des scripts.
Mais si l'essentiel est d'ajouter 2 séquences d'échappement et un bout de replace, il y a quelque chose qui m'échappe.
Puisqu'il faut tout coder, à la virgule près, les 2 scripts ci-dessous devraient convenir.
testnews.sh
Code : Tout sélectionner
#!/bin/sh
sed_news () {
echo -e "\n \\e[01;31m\t\t >> News Archlinux.fr << \\e[00m\n$(
curl -s https://archlinux.fr/feed | sed '/<title\|<pubDate/!d;s/\t*//g;s/<\/*title>/ - /g;s/[0-9]*:.*/\\e[00m/g;s/’/'"'"'/g;s/–/-/g;/Archlinux.fr/d' |
sed 'N;s/\n<pubDate>/\\033[1;34m/g;P;D;') \n"
}
awk_news () {
curl https://archlinux.fr/feed -s |
awk 'BEGIN {red="\033[1;31m"; bleu="\033[34m"; defo="\033[0m"; print red"\n\t\t>> News Archlinux.fr <<"defo} /<title>/ {z=substr($0,10,length($0)-17)}
/<pubDate>/ {gsub("’", "\x27", z); print z "||" bleu $2" " $3 " " $4 defo}'
}
alias ak_news='curl https://archlinux.fr/feed -s |
awk '"'"' BEGIN {red="\033[31m"; bleu="\033[34m"; defo="\033[0m"; print red"\n\t\t>> News Archlinux.fr <<"defo}
/<title>/ {z=substr($0,10,length($0)-17)} /<pubDate>/ {gsub("’", "\x27", z);print z "||" bleu $2" " $3 " " $4 defo}'"'"
waitnsea a écrit :Effectivement la commande est plus simple et tout à fait efficace, mais elle ne se laisse pas transformer en alias
Mauvaise approche, ce n'est pas parce qu'on ne sait pas que ça ne le fait pas (alias ak_news 1er script)
waitnsea a écrit :elle est plus rapide aussi (l'initiale)...
A-tu fais des tests ?
Pour avoir tester les 2 deux, les temps de réponse sont du même ordre : quelques millisecondes d'écart sur un i5.
Le temps de latence n'est pas au même endroit, avant l'affichage de ">> News Archlinux.fr <<" dans un cas, après dans l'autre ce qui explique ton impression.
Pour des choses un tant soit peu complexes, Awk me parait plus clair et plus maintenable que Sed, surtout si on n'utilise celui-ci qu'occasionnellement (avis personnel)
Le 2ème script s'utilise ainsi :
curl -s https://archlinux.fr/feed | ./awknews
awknews
Code : Tout sélectionner
#!/usr/bin/awk -f
BEGIN {
red="\033[31m"
bleu="\033[34m"
defo="\033[0m"
print red "\n\t\t>> News Archlinux.fr <<" defo
}
/<title>/ {
z=substr($0,10,length($0)-17)
}
/<pubDate>/ {
gsub("’", "\x27", z)
print z "||" bleu $2" " $3 " " $4 defo
}
Re: [script] Les news dans le terminal (résolu)
Publié : ven. 18 juil. 2014, 11:26
par waitnsea
Merci avi3000,
J'ai beaucoup à apprendre...
Re: [script] Les news dans le terminal (résolu)
Publié : ven. 18 juil. 2014, 22:37
par 4nti7rust
Salut,
Je pensais être le seul utilisateur de cet horrible UBER-regex-rss-parser
tueur de chatons ... Mais il semblerait que certains en redemandent.
Voici donc la version que j'utilise actuellement :
Code : Tout sélectionner
echo -e "\n\\e[01;31m> News Archlinux.fr\\e[00m\n$(curl -s https://archlinux.fr/feed | sed '/<title\|<pubDate/!d;s/\t*//g;s/<title>/ - /g;s/<\/title>//g;s/ [0-9]* [0-9]*:.*/\\e[00m/g;s/’/'"'"'/g;s/–//g;/Archlinux.fr/d;s/intervention manuelle/\\033[1;33mintervention manuelle\\e[00m/g;' | sed 'N;s/\n<pubDate>/ - \\033[1;34m/g;P;D;') \n"
Je pense que le script de
avi3000 est bien mieux. J’hésite à faire une version php histoire d'utiliser un vrai parseur.
[
EDIT] Script de
avi3000 modifié pour obtenir le même résultat qu'avec la version sed :
Code : Tout sélectionner
#!/usr/bin/awk -f
BEGIN {
red="\033[1;31m"
bleu="\033[1;34m"
defo="\033[0m"
jaun="\033[1;33m"
print red "\n> News Archlinux.fr" defo
}
/<title>/ {
z=substr($0,10,length($0)-17)
gsub("intervention manuelle", jaun "intervention manuelle" defo, z)
}
/<pubDate>/ {
gsub("’", "\x27", z)
print " - " z " - " bleu $2" " $3 " " $4 defo
}
Re: [script] Les news dans le terminal (résolu)
Publié : sam. 19 juil. 2014, 00:03
par avi3000
Je vois qu'on a envie de se lancer dans le codage récréatif.
une version bash, pour varier les plaisirs:
curl -s https://archlinux.fr/feed | ./sh_news
sh_news
Code : Tout sélectionner
#!/bin/sh
red="\033[31m"
bleu="\033[34m"
defo="\033[0m"
on_one="$red \n\t\t>> News Archlinux.fr <<$defo"
while read z; do
[ "${z:0:7}" = '<title>' ] && {
z=${z//‘/\\x27}
z=${z//’/\\x27}
z=${z//–/-}
z=${z//>/>}
[ "$on_one" = '' ] && echo -en "${z:7:-8}" || echo -e "$on_one"
on_one=''
}
[ "${z:0:9}" = '<pubDate>' ] && {
echo -e " || $bleu${z:14:-25}$defo"
}
done
echo
un autre méthode (printf) avec awk permettant de déplacer le temps d'attente :
awknews2
Code : Tout sélectionner
#!/usr/bin/awk -f
BEGIN {
red="\033[31m"
bleu="\033[34m"
defo="\033[0m"
on_one=red "\n\t\t>> News Archlinux.fr <<" defo
}
/<title>/ {
if ( on_one ) {
print(on_one)
on_one=""
}
else
printf(gensub("’", "\x27", "g", substr($0,10,length($0)-17)))
}
/<pubDate>/ {
print("||" bleu $2" " $3 " " $4 defo)
}
J'ai fait quelques tests de temps de réponse avec un fichier local.
Les versions awk sont 2 fois plus rapides que la version sed (normal 2 appels sed, 1 appel awk) et 3 fois plus rapides que la version bash.
Il existe un vrai parser xml pour awk : getXMLEVENT.awk.
Mais son usage n'est pas nécessaire pour des cas simples comme ce fil de nouvelles.
Re: [script] Les news dans le terminal (résolu)
Publié : dim. 20 juil. 2014, 11:57
par avi3000
la version python3:
curl -s https://archlinux.fr/feed | ./news.py
news.py
Code : Tout sélectionner
#!/usr/bin/env python
import sys
red = "\033[31m"
bleu = "\033[34m"
defo = "\033[0m"
buf = False
xml = sys.stdin.read().splitlines()
for z in xml :
z = z.lstrip()
if z[0:7] == "<title>" :
if buf :
buf += '\n' + z[7:-8].replace('’', 'ʼ') + ' || '
else :
buf = red + "\n\t\t>> News Archlinux.fr <<" + defo
elif z[0:9] == "<pubDate>" :
buf += bleu + z[14:-25] + defo
print(buf)
la version script C :
curl -s https://archlinux.fr/feed | ./news.c
(pacman -S tcc, si ce n'est pas déjà fait)
news.c
Code : Tout sélectionner
#!/usr/bin/tcc -run
#include <stdio.h>
#include <string.h>
#define MAX_LINE_SIZE 1024
#define RED "\033[31m"
#define BLEU "\033[34m"
#define DEFO "\033[0m"
int main() {
char line[MAX_LINE_SIZE];
char buf[MAX_LINE_SIZE];
char *z, *y;
int on_one = 1;
while ( fgets(line, MAX_LINE_SIZE, stdin) ) {
if ( z = strstr(line, "<title>") ) {
if ( on_one ) {
printf("%s\n\t\t>> News Archlinux.fr <<%s\n", RED, DEFO);
on_one = 0;
}
else {
z[strlen(z)-9] = '\0';
while ( y = strstr(z, "’") ) {
y[0] = '\'';
strcpy(buf, y+7);
strcpy(y+1, buf);
}
printf("%s", z+7);
}
}
else if ( z = strstr(line, "<pubDate>") ) {
z[strlen(z)-26] = '\0';
printf(" || %s%s%s\n", BLEU, z+14, DEFO);
}
}
return 0;
}
la version sed améliorée :
echo -e "\n$(curl -s https://archlinux.fr/feed | ./sednews2)\n"
sednews2
Code : Tout sélectionner
#!/usr/bin/sed -f
/<title\|<pubDate\|<rss /!d;
s/\t*//g;
/<rss / {
s/.*/\t\t\\e[31m>> News Archlinux.fr <<\\e[0m/
}
/<title>/ {
s,</*title>, - ,g
s/’/’/g
h
D
}
/<pubDate>/ {
s/^.\{14\}\(.\{11\}\).*$/\\e[34m\1\\e[0m/
H
g
s/\n//;
}
Temps de réponse ( boucle de 100 sur un fichier local ) :
Code : Tout sélectionner
le script C compilé 0.12s
le script C interprété 0.30s
le script awknews2 0.40s
le script sednews2 0.40s
la version sed de base 0.70s
le script bash sh_news 1.05s
le script python news.py 1.65s
je vous laisse le soin de coder les versions, ruby, perl, php, java, ...
Re: [script] Les news dans le terminal (résolu)
Publié : lun. 18 nov. 2019, 12:23
par avi3000
Une version bash 2019.
Le lien peut être passé en paramètre.
Code : Tout sélectionner
#!/bin/bash
red="\033[31m"
bleu="\033[34m"
defo="\033[0m"
on_one="\n\t\t>> News Archlinux.fr <<$defo"
while read z; do
[ "${z:0:7}" = '<title>' ] && {
z=${z//‘/\\x27}
z=${z//’/\\x27}
z=${z//–/-}
z=${z//>/>}
[ "$on_one" = '' ] && titre=${z:7:-8} || echo -e "$red$on_one"
on_one=''
}
[ "${z:0:9}" = '<pubDate>' ] && {
echo -e "$bleu${z:14:-25}$defo $titre"
}
done < <(curl -s ${@:-https://archlinux.fr/feed})
echo
Re: [script] Les news dans le terminal (résolu)
Publié : lun. 18 nov. 2019, 16:54
par waitnsea
avi3000 a écrit : ↑lun. 18 nov. 2019, 12:23
Une version bash 2019.
Merci de la mise à jour...Impeccable.
Sans être exigeant ni critique, car je m'en accommode fort bien depuis 5 ans, y-a-t’il moyen de corriger la mauvaise prise en charge des accentués :
Code : Tout sélectionner
...Remplacement du groupe ‘base’...
La mise à jour de astyle>=3.1-2
Re: [script] Les news dans le terminal (résolu)
Publié : lun. 18 nov. 2019, 18:07
par laurent85
Bonjour,
Tu dois avoir un pb de locale moi l'affichage est impeccable en console et xorg.
Re: [script] Les news dans le terminal (résolu)
Publié : lun. 18 nov. 2019, 18:26
par avi3000
waitnsea a écrit : ↑lun. 18 nov. 2019, 16:54
Sans être exigeant ni critique, car je m'en accommode fort bien depuis 5 ans, y-a-t’il moyen de corriger la mauvaise prise en charge des accentués :
Code : Tout sélectionner
...Remplacement du groupe ‘base’...
La mise à jour de astyle>=3.1-2
Il faut bien tout lire moet hennesy. C'était corrigé dans la version bash 2019.
Pour les autre versions, à chacun de se démerder, c'est comme ça qu'on apprend.
Re: [script] Les news dans le terminal (résolu)
Publié : lun. 18 nov. 2019, 19:07
par waitnsea
@ laurent85 - Non mes locales sont OK, merci
@avi3000 - J'avais bien lu mais mal tapé mes commandes de copie dans vim et gardé la vieille version...! le cru 2019 est effectivement sans erreur, merci aussi
Re: [script] Les news dans le terminal (résolu)
Publié : lun. 18 nov. 2019, 23:11
par sukolyn
Code : Tout sélectionner
wget -qO - archlinux.fr/feed \
| xmlstarlet sel -D --net -E 'utf-8' -T -t -m '//channel/item' -n -v 'pubDate' -n -o '^[[01m' -v 'title' -o '^[[0m' -n -v 'description' -n - \
| sed 's/’/'\''/g; s/…/.../g'
--
edit:
^[
est obtenu en tapant
Ctrl-v-[
Re: [script] Les news dans le terminal (résolu)
Publié : mar. 19 nov. 2019, 19:21
par avi3000
@sukolyn
ta solution n'est pas terrible:
tu remplace bash + un sous-shell curl par 3 processus wget + xmlstarlet + sed.
c'est un process de trop.
et un paquet supplémentaire à installer.
un version plus complète
Code : Tout sélectionner
#!/bin/bash
red="\033[31m"
bleu="\033[34m"
defo="\033[0m"
on_one="\n\t\t>> News Archlinux.fr <<$defo"
parse_z () {
z=${z//‘/\\x27}
z=${z//’/\\x27}
z=${z//–/-}
z=${z//…/...}
z=${z//>/>}
}
while read z; do
[ "${z:0:7}" = '<title>' ] && {
parse_z
[ "$on_one" = '' ] && titre=${z:7:-8} || echo -e "$red$on_one"
on_one=''
}
[ "${z:0:9}" = '<pubDate>' ] && {
echo -e "$bleu${z:14:-25}$defo $titre"
}
[ "${z:0:14}" = '<description><' ] && {
z=${z#*A[}
z=${z%]]>*}
parse_z
echo -e "$z\n"
}
done < <(curl -s ${@:-https://archlinux.fr/feed})
echo
# vim: ts=4 sw=4 :
Re: [script] Les news dans le terminal (résolu)
Publié : mar. 19 nov. 2019, 22:05
par sukolyn
mais pourquoi parfois y a-t-il par exemple des apostrophes, et parfois une "entité" HTML (#&8217;) ?
Re: [script] Les news dans le terminal (résolu)
Publié : mar. 19 nov. 2019, 23:40
par avi3000
parce que la vie n'est pas facile et le rédacteur de news est taquin.
Re: [script] Les news dans le terminal (résolu)
Publié : mer. 20 nov. 2019, 00:53
par sukolyn
une autre expression me vient à l'esprit, qui s'allitère plutôt bien à "est taquin", mais bon.
je préférerais un case/esac à ces test
s.
Re: [script] Les news dans le terminal (résolu)
Publié : mer. 20 nov. 2019, 03:09
par sukolyn
Code : Tout sélectionner
#!/usr/bin/python
import requests # il faut installer python-requests. ça ira ?
from xml.etree import ElementTree as ET
import textwrap
news = requests.get('https://archlinux.fr/feed')
root = ET.fromstring(news.text)
for t in root.findall("channel/item"):
title = t.find('title').text
date = t.find('pubDate').text
desc = t.find('description').text
desc = desc.replace('…','...')
desc = desc.replace('’',"'")
desc = desc.replace('‘',"'")
desc = desc.replace('–',"-")
desc = textwrap.fill(desc,80)
print("%s\n\033[01;31m%s\n\033[00;36m%s\033[00m\n"%(date, title, desc))
Re: [script] Les news dans le terminal (résolu)
Publié : mer. 20 nov. 2019, 05:39
par waitnsea
Et que c'est beau en plus !
Re: [script] Les news dans le terminal (résolu)
Publié : mer. 20 nov. 2019, 11:54
par sukolyn
j'ai récupéré une fonction pour éviter la succession de
replace()
qui ne me plaît pas :
Code : Tout sélectionner
#!/usr/bin/python
import requests
from xml.etree import ElementTree as ET
import textwrap
def replace_all(text, dico):
for i, j in dico.items():
text = text.replace(i, j)
return text
entities = { '…': '...', '‘': "'", '’': "'", '–': '-' }
news = requests.get('https://archlinux.fr/feed')
root = ET.fromstring(news.text)
for t in root.findall("channel/item"):
title = t.find('title').text
date = t.find('pubDate').text
desc = replace_all(t.find('description').text , entities)
print("%s\n\033[01;31m%s\n\033[00;36m%s\033[00m\n"%(date, title, textwrap.fill(desc,100)))
ainsi, seul le dictionnaire s'allonge à mesure qu'on rencontre des "entités" à convertir.
Re: [script] Les news dans le terminal (résolu)
Publié : mer. 20 nov. 2019, 13:13
par avi3000
Un petit concours de code !!
@sukolyn il faut installer python-requests. ça ira ?
Non, 9 paquets et 5,40Mo installé pour traiter 3 noeuds, c'est prendre un marteau pour écraser une mouche.
Code : Tout sélectionner
pacman -S python-requests
résolution des dépendances…
recherche des conflits entre paquets…
Paquets (9) python-appdirs-1.4.3-5 python-chardet-3.0.4-4 python-idna-2.8-3 python-packaging-19.2-5 python-pyparsing-2.4.5-1 python-setuptools-1:41.2.0-5 python-six-1.13.0-2 python-urllib3-1.25.7-1 python-requests-2.22.0-3
Taille totale du téléchargement : 0,92 MiB
Taille totale installée : 5,40 MiB
J'avais fait des tests comparatifs
ici.
python3 est toujours le moins performant.
J'ai refait des tests avec tes versions sur un fichier local. Les résultats sont encore sans appel.
Modifications pour traiter le fichier local (j'ai également supprimer le textwrap pour comparer le même traitement)
Code : Tout sélectionner
#!/usr/bin/python
def replace_all(text, dico):
for i, j in dico.items():
text = text.replace(i, j)
return text
entities = { '…': '...', '‘': "'", '’': "'", '–': '-' }
from lxml.etree import parse as ET
root = ET('./feed')
for t in root.findall("channel/item"):
title = t.find('title').text
date = t.find('pubDate').text
desc = replace_all(t.find('description').text , entities)
print("%s\n\033[01;31m%s\n\033[00;36m%s\033[00m\n"%(date, title, desc))
Les résultats n'ont pas changé
Code : Tout sélectionner
time for (( i=100; i>0; i-- )); do ./news2.py >/dev/null;done
real 0m3,360s user 0m2,982s sys 0m0,383s
time for (( i=100; i>0; i-- )); do ./news.py >/dev/null;done
real 0m3,338s user 0m2,842s sys 0m0,501s
time for (( i=100; i>0; i-- )); do ./news.sh ./feed >/dev/null;done
real 0m0,841s user 0m0,619s sys 0m0,241s
ta version est moins rapide que ma version python de 2014.
Code : Tout sélectionner
time for (( i=100; i>0; i-- )); do cat ./feed | ./mon_python.py >/dev/null;done
real 0m1,242s user 0m1,106s sys 0m0,207s
En étant plus proche du pseudo-code, le programme est portable dans beaucoup de langage.
Rapidité d'écriture vs rapidité d'éxécution, mon choix est fait depuis longtemps.
Je pense que le tien aussi.
Re: [script] Les news dans le terminal (résolu)
Publié : mer. 20 nov. 2019, 13:56
par sukolyn
c'est un peu déstabilisant de voir que bash, qui est réputé être lent, est plus rapide que des outils conçus pour traiter des fichiers d'un format particulier (ici, du XML).
l'intérêt de ces outils est que s'il vient un jour au taquin l'idée de mettre tout le fichier sur une seule ligne, le script sera toujours fonctionnel.
rapidité/stabilité...