[script] Les news dans le terminal (résolu)

Autres projets et contributions
avi3000
Chu Ko Nu
Messages : 325
Inscription : dim. 19 juin 2011, 18:53
Localisation : dans le neuf trois

Re: [script] Les news dans le terminal (résolu)

Message par avi3000 » jeu. 17 juil. 2014, 22:15

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/&#8217;/'"'"'/g;s/&#8211;/-/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("&#8217;", "\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("&#8217;", "\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("&#8217;", "\x27", z)
     print z "||" bleu $2" " $3 " " $4 defo
}

Avatar de l’utilisateur
waitnsea
Maître du Kyudo
Messages : 1851
Inscription : jeu. 15 mars 2012, 05:08

Re: [script] Les news dans le terminal (résolu)

Message par waitnsea » ven. 18 juil. 2014, 11:26

Merci avi3000,
J'ai beaucoup à apprendre...
LENOVO Y700-341SH i7-6700 3.4gHZ 1 SSD + 2HDD - Arch/KDE - NVidia GeForce GeForce GTX 750 T
Sauvegardes quotidiennes de mes système et données par BORG

4nti7rust
Hankyu
Messages : 34
Inscription : dim. 13 nov. 2011, 15:22

Re: [script] Les news dans le terminal (résolu)

Message par 4nti7rust » ven. 18 juil. 2014, 22:37

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/&#8217;/'"'"'/g;s/&#8211;//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("&#8217;", "\x27", z)
     print " - " z " - " bleu $2" " $3 " " $4 defo
}

avi3000
Chu Ko Nu
Messages : 325
Inscription : dim. 19 juin 2011, 18:53
Localisation : dans le neuf trois

Re: [script] Les news dans le terminal (résolu)

Message par avi3000 » sam. 19 juil. 2014, 00:03

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="\034[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//&#8217;/\\x27}
          [ "$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("&#8217;", "\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.

avi3000
Chu Ko Nu
Messages : 325
Inscription : dim. 19 juin 2011, 18:53
Localisation : dans le neuf trois

Re: [script] Les news dans le terminal (résolu)

Message par avi3000 » dim. 20 juil. 2014, 11:57

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('&#8217;', 'ʼ') + ' || '
        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, "&#8217;") ) {
                    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/&#8217;/’/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, ...

Répondre