[Home] [en]

SHELECT

Copyright (C) 2011,2018 Dominique Corfa dominique.corfa@free.fr

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see http://www.gnu.org/licenses.

Voici un programme écrit en bash (demande une version de bash au moins 4.0), SHELECT permettant d'agglomérer les commandes sort, cut, awk de telle manière qu'on puisse les utiliser sur des fichiers textes équivalent à des tables d'une base de données relationnelle, et dans une syntaxe proche de de SQL.

Je vous invite à le tester, l'utiliser et l'améliorer, mais en respectant les termes de la licence GNU General Public Licence version 3 et ultérieures.

Installation

C'est un simple script bash. Vous devez avoir bash pour pouvoir l'utiliser.

Copier le fichier SHELECT dans n'importe quel répertoire inclu dans votre $PATH, et donner lui les droits d'exécution. C'est fait,vous pouvez l'utiliser.

J'ai signé le fichier SHELECT avec ma clé. Vous pouvez vérifier cette signature en insérant ma clé publique dans votre propre trousseau de clé.

Utilisation

La syntaxe de la commande SHELECT est obtenue en tapant :
    $ SHELECT help
  

Exemples

Utilisé comme cat.

$ SHELECT \* FROM table
# id,nom,prenom
01,De La Fontaine,Jean
02,Marcœur,Albert
03,Klee,Paul

Utilisé comme sort.

$ SHELECT \* FROM table ORDER BY nom
# id,nom,prenom
01,De La Fontaine,Jean
03,Klee,Paul
02,Marcœur,Albert

Utilisé comme cut. Noter que cut n'est pas utilisé car il ne respecte pas l'ordre imposé aux colonnes résultat.

$ SHELECT prenom nom FROM table
# prenom,nom
Jean,De La Fontaine
Albert,Marcœur
Paul,Klee

Utilisé comme awk pour sélectionner des lignes.

$ SHELECT \* FROM table WHERE 'prenom=="Jean"'
# id,nom,prenom
01,De La Fontaine,Jean

Prenons l'exemple traditionnel de client, et de commandes. Imaginons nous dans une session bash, les commandes tapées par l'opérateur sont en gras. Voici les quelques fichiers préparés pour l'exemple. Notez que nous avons créé des liens symboliques pour pouvoir se référer au fichiers avec une seule lettre, un peu comme avec le mot clé 'AS' dans la syntaxe SQL.

$ ls -l
total 16
lrwxrwxrwx 1 dominique dominique  7 2011-12-11 22:04 a -> article
-rw-r--r-- 1 dominique dominique 55 2011-12-11 22:01 article
lrwxrwxrwx 1 dominique dominique  8 2011-12-11 21:43 c -> customer
-rw-r--r-- 1 dominique dominique 78 2011-12-11 21:40 customer
lrwxrwxrwx 1 dominique dominique  7 2011-12-11 22:04 i -> invoice
-rw-r--r-- 1 dominique dominique 33 2011-12-11 22:01 invoice
lrwxrwxrwx 1 dominique dominique  5 2011-12-11 22:04 o -> order
-rw-r--r-- 1 dominique dominique 80 2011-12-11 21:46 order

Un mini fichier client. Aujourd'hui tout se fait par téléphone.

$ SHELECT \* FROM customer
# id,name,phone
1,Corfa,33678912345
2,Dupont,33666666666
3,Dupond,33606060606

Un mini fichier d'articles. Notez que l'étoile '*' est protégée contre l'expansion du shell.

$ SHELECT \* FROM article
# id,name,price
1,machin,3
2,truc,16.50
3,bidule,9.30
4,chose,1
5,objet,9.99

Un fichier pour les commandes, customer fait référence à l'identification du client.

$ SHELECT \* FROM order
# id,date,customer,delivered
1,2011-12-10,1,1
2,2011-12-10,3,0
3,2011-12-11,1,0

Et la composition des commandes, faisant référence d'une part aux identifiants des commandes et aux articles commandés et servant à faire la facture. Il s'agit donc d'une table matérialisant une relation '1..*'.

$ SHELECT \* FROM invoice
# order,article
1,1
1,1
1,1
1,3
3,5
3,5
2,3
2,3
2,3
2,4
2,4
2,4
2,4
2,4
2,4

Regardons par exemple les commandes à livrer :


$ SHELECT o.date c.name a.name a.price
  FROM o JOIN c ON o.customer=c.id JOIN i ON o.id=i.order JOIN a ON i.article=a.id
  WHERE 'o.delivered==0'

# date,name,name,price
2011-12-10,Dupond,bidule,9.30
2011-12-10,Dupond,bidule,9.30
2011-12-10,Dupond,bidule,9.30
2011-12-10,Dupond,chose,1
2011-12-10,Dupond,chose,1
2011-12-10,Dupond,chose,1
2011-12-10,Dupond,chose,1
2011-12-10,Dupond,chose,1
2011-12-10,Dupond,chose,1
2011-12-11,Corfa,objet,9.99
2011-12-11,Corfa,objet,9.99

Ce qui pourra se résumer par :


$ SHELECT o.date c.name a.name a.price 'count(a.name)' 'sum(a.price)'
  FROM o JOIN c ON o.customer=c.id JOIN i ON o.id=i.order JOIN a ON i.article=a.id
  WHERE 'o.delivered==0'
  GROUP BY o.date c.name a.name a.price

# date,name,name,price,count(a.name),sum(a.price)
2011-12-10,Dupond,bidule,9.30,3,27.9
2011-12-10,Dupond,chose,1,6,6
2011-12-11,Corfa,objet,9.99,2,19.98