Séance 3 : Flux de données§
Département Informatique (IUT Lyon 1)
Ce travail est sous licence Creative Commons Attribution-ShareAlike 3.0 France.
Département Informatique (IUT Lyon 1)
Ce travail est sous licence Creative Commons Attribution-ShareAlike 3.0 France.
Que fait le programme suivant ?
#include <readline/readline.h>
int main(int argc, char* argv[]) {
char* nom = readline("Quel est votre nom ? ");
printf("Bonjour %s !\n", nom);
}
Note
Réponse typique : il lit une chaîne depuis le clavier, puis affiche une chaîne à l'écran. Mais c'est en fait un cas pariculier de ce qu'il fait.
Sous Linux, la plupart des programmes démarrent avec 3 flux de données préalablement ouverts :
Note
On emploie parfois le mot « fichier » plutôt que flux, bien qu'il prête à confusion.
Les processus lancés par le shell héritent de ses flux standard, et donc correspondent par défaut au clavier et a l'affichage du terminal.
Mais il est possible de changer cela.
Une ligne de commande peut comporter un ou plusieurs des éléments suivants :
<
suivi d'un nom de fichier (chemin)>
suivi d'un nom de fichier (chemin)2>
suivi d'un nom de fichier (chemin)Ces éléments redirigent (ou « rebranchent ») l'un des flux standards (l'entrée, la sortie et l'erreur standard, respectivement) sur le fichier indiqué.
Indication
Les redirections sont interprétéss par les shell avant d'exécuter le programme, et ne sont donc pas vues par le programme.
Exemple :
ls -l >mes_fichiers.txt
/dev/null
est un fichier virtuel présent sur tous les systèmes UNIX.
Il agit comme un « trou noir », tout ce qui est écrit dans ce fichiers est simplement supprimé.
Exemple :
# n'affiche que les messages d'erreurs
# (répertoires non autorisés pour l'utilisateur)
ls /var/*/* >/dev/null
Les redirections classiques >
et 2>
vident le fichier destination avant d'écrire dedans.
Si on souhaite conserver le contenu précédent du fichier,
on peut utiliser à la place >>
ou 2>>
, respectivement.
Exemple :
ls -l Documents >>mes_fichiers.txt
Compte les mots (ou d'autres choses) sur son entrée standard.
En l'absence d'options, affiche le nombre de lignes, de mots et d'octets.
-c
,
--bytes
Affiche le nombre d'octets.
-w
,
--words
Affiche le nombre de mots.
-l
,
--lines
Affiche le nombre de lignes.
-L
,
--max-line-length
Affiche la longueur de la ligne la plus longue.
Trie les lignes lues sur l'entrée standard, et les affiche dans l'ordre sur la sortie standard.
-r
,
--reverse
Inverse l'ordre du tri.
-n
,
--numeric-sort
Interprète les valeurs comme des nombres si possible.
Note
Dans l'ordre alphabétique (utilisé par défaut), 10
arrive avant 2
par exemple.
-k
,
--key
=NUMÉRO
Le champs sur lequel trier (les champs sont délimitées par tous les types d'espaces).
Note
En fait l'option -k
est beaucoup plus flexible que cela.
-t
,
--field-separator
=CARACTÈRE
Utilise CARACTÈRE
comme délimiteur de champs pour -k
,
au lieu des espaces.
Reproduit sur sa sortie standard une sous-partie de chaque ligne lue sur son entrée standard.
-f
,
--fields
=LIST
Ne conserve que les champs spécifiés par LIST
,
qui est une liste séparée par des virgules de numéros
(le premier champs est a le numéro 1)
ou de plages de numéros.
Les champs sont délimités par des tabulations.
-d
,
--delimiter
=CARACTÈRE
Utilise CARACTÈRE
comme délimiteur de champs pour -f
,
au lieu des tabulation.
-c
,
--characters
=LIST
Ne conserve que les caractères spécifiés par LIST
,
avec la même syntaxe que pour -f
.
# ne garde que les colonnes 1 et 3
cut -d, -f1,3 <data.csv >columns.csv
# affiche les noms d'utilisateurs inscrits
cut -d: -f1 </etc/passwd
# tronque à 10 caractères chaque ligne de src
cut -c1-10 <src >dest
N'affiche sur la sortie standard que les lignes (lues sur l'entrée standard)
contenant l'expression régulière <regex>
.
-i
,
--ignore-case
Ignore les différences de casse (différence majuscule/minuscule) entre le texte lu et l'expression régulière.
-v
,
--invert-match
Au lieu d'afficher les lignes qui contiennent <regex>
,
affiche celles qui ne la contiennent pas.
Reproduit sur sa sortie standard le texte lu sur l'entrée standard, en modifiant (première variante) ou supprimant (deuxième variante) certains caractères.
<set1>
Une liste de caractères, énumérés en extension,
ou sous forme de plages de caractères séparés par un tiret -
.
Exemple : 02468
, a-zàâéèêîôû
, a-zA-Z
-c
,
--complement
Transforme les caractères qui n'appartiennent pas à <set1>
.
<set2>
Une liste de caractères, suivant les mêmes règles que <set1>
.
Chaque caractère de <set1>
sera remplacé par le caractère correspondant de <set2>
.
Si <set2>
est plus court que <set1>
,
le dernier caractère est implicitement répété autant de fois que nécessaire.
-d
,
--delete
Supprime les éléments de <set1>
.
# remplace toutes les majuscules par des minuscules
tr A-Z a-z <src >dest
# remplace tous les chiffres par X
tr 0-9 X <src >dest
# remplace tout ce qui n'est pas une lettre par une espace
tr -c A-Za-z " " <src >dest
# supprime les espaces, tabulations, retours à la ligne
tr -d " \t\n" <src >dest
Reproduit sur sa sortie standard le texte lu sur l'entrée standard,
en remplaçant toutes les occurences de l'expression régulière
par le texte <subst>
(qui peut être vide).
Note
sed
(serial editor) est en fait un éditeur de texte programmable.
Ceci n'est qu'une des nombreuses instructions qu'il supporte.
Une expression régulière (ou regex) décrit dans une syntaxe spécialisée une famille de chaînes de caractères.
Par exemple :
a.*z
: tout chaîne qui commence par a
et se termine par z
[a-z]{1,5}
: tous les mots de 1 à 5 lettres minuscules\d{2}/\d{2}/\d{4}
: toutes les dates au format jj/mm/aaaa (un peu plus)[a-z0-9.-]+@[a-z0-9.-]+(\.[a-z]+)*
: toutes les adresses e-mail (un peu moins)Les expressions régulières sont également utilisables
.
: n'importe quel caractère[...]
: un caractère appartenant à la séquence décrite, exemples :[xyz]
: un des caractères x
, y
ou z
[^xyz]
: n'importe quel caractère autre que x
, y
ou z
[0-9]
: n'importe quel chiffre décimal[a-zA-Z_]
: n'importe quelle lettre minuscule ou majuscule, ou l'underscore.^
: le début de la ligne$
: la fin de la ligneSi on suppose que a et b sont des expressions régulières quelconques :
(a)*
: un texte qui satisfait a zéro fois ou plus(a)+
: un texte qui satisfait a une fois ou plus(a)?
: un texte qui satisfait a zéro ou une fois(a){i,j}
: un texte qui satisfait a entre i et j fois(a)|(b)
: un texte qui satisfait a ou bPour éviter que egrep
ou sed
n'interprète un caractère spécial
on le fera précéder d'un antislash (\
).
Exemple:
# affiche toutes les lignes de src qui contiennent un a suivi d'une étoile
egrep "a\*" <src
Avertissement
*
).egrep
ou sed
doivent eux-même être échappés pour ne pas être interprétés par le shell !Un tube (en anglais pipe) est un canal de communication quasi-synchrone entre deux programmes.
L'un des programmes écrit des données à une « extrémité » du tube ; l'autres les récupère en lisant à l'autres « extrémité ».
Contrairement à un fichier, les données écrites dans le tube ne sont pas stockées.
En concaténant deux lignes de commandes, séparées par le caractère |
,
on demande au shell
Le shell attend ensuite la fin des deux programmes.
# affiche les fichiers dont le nom est composé
# uniquement de minuscules ou uniquement de majuscules
ls | egrep "([a-z]+)|([A-Z]+)"
Une telle ligne de commande est appelée un pipeline.
Il est possible de concaténer plus de deux commandes ainsi.
# affiche les fichiers dont le nom a le format IMG_<numéro>.png
# triés par numéro
ls | egrep "IMG_[0-9]+.png" | sort -n -k2 -t_