Il y a plein d’outils disponibles pour filtrer du texte. Voilà des exemples que j’utilise souvent.
Filtrage des champs d’un fichier de type csv
On parle ici de fichiers formatés en colonnes, avec un séparateur simple (ie. le séparateur n’apparaît en aucun cas dans les colonnes). Je peux me permettre cette restriction, car c’est souvent moi qui les génère, je sais donc à quoi m’attendre.
Choix des colonnes
Pour simplement sélectionner les colonnes à voir,
le plus simple est d’utiliser cut
:
-
pour mentionner le séparateur, il faut utiliser l’option
--delimiter=,
ou-d,
-
pour sélectionner les champs, c’est l’option
-field
ou-f
suivie des champs à sélectionner numérotés à partir de 1. Par exemple, pour afficher les champs jusqu’au 3$^e$, 6 à 8, et de 12 à la fin :$ cut --field=-3,6-8,12-
-
pour voir les champs qui ne sont pas dans la sélection précédente, il y a l’option
--complement
. Par exemple, pour supprimer la 3e colonne :$ cut --field=3 --complement
Reformatage
Si, en plus de sélectionner les colonnes,
on veut par exemple en modifier l’ordre, ou encore modifier le formatage,
il vaut mieux utiliser awk
:
-
pour mentionner le séparateur, il faut utiliser l’option
-F,
(ou la variableFS
dans la règleBEGIN
) -
pour transformer l’affichage, on utilise
printf
. Par exemple :awk -F, '{printf "%s --- %s : %s\n", $2, $4, ($6~/ok/ ? "OK" : "KO") }'
Tri
Pour trier suivant une colonne :
-
pour mentionner le séparateur, il faut utiliser l’option
-t,
(ou--field-separator=,
) -
pour choisir la colonne, c’est
-k 2
(ou--key=2
). Il faut noter qu’avec cette option, on peut aussi choisir le type de tri. Les plus courants sont:-
-n
(ou--numeric-sort
) -
-d
(ou--dictionary-order
)On peut aussi préciser:
-
-b
(ou--ignore-leading-blanks
) -
-f
(ou--ignore-case
)
-
Par exemple :
$ sort -t, -k 12n,1f
(voir le man pour plus de détails).
sed
Pour ne garder que les lignes transformées
Pour ne garder que les lignes sur lesquelles on fait une transformation,
on peut bien sûr utiliser grep
:
$ xwininfo -root | grep "-geometry" | sed -e '^.* \([0-9]*\)x\([0-9]*\).*$/ ; w=\1 ; h=\2/'
Mais c’est quand même un peu dommage, alors qu’on peut faire la même chose avec juste sed
:
$ xwininfo -root | sed -e '/^ *-geometry/!d ; s/^.* \([0-9]*\)x\([0-9]*\).*$/ ; w=\1 ; h=\2/'
Encore mieux lorsqu’on ne souhaite pas spécifier explicitement les lignes à garder, on peut simplement ne garder que celle qui subisse une transformation:
xwininfo -root \
| sed -e 's/.*Width: \([0-9]*\)/w=\1/' \
-e 's/.*Height: \([0-9]*\)/h=\1/' \
-e 't' -e 'd' )
Le t
signifie que si l’une des substitutions a été effectuée sur la ligne, on se branche à un label.
Ici, on n’a pas spécifié le label, et on va donc à la fin du script. Sinon (la ligne ne correspond à aucun des filtres), on fait d
, c’est à dire que l’on détruit la ligne.
Pour effacer le début d’un fichier jusqu'à une RE exclue
La commande suivante ne fait pas ce qu’on veut,
car elle ne garde pas la ligne contenant toto
:
$ sed -e "1,/toto/d" fichier.txt
Si on souhaite la garder, il faut faire:
$ sed -e "1,/toto/{/toto/b ; d}" fichier.txt
C’est semblable à l’autre, sauf que sur la ligne contenant toto
,
on se branche (b
) à la fin de la commande
(car on n’a pas précisé de label de branchement),
c’est-à-dire qu’on ne détruit pas cette ligne (d
).
Pour ne garder que les lignes entre deux RE
Effacer ce qui n’est pas entre les deux RE :
$ sed -e "/toto/,/titi/!d"
ou encore, ne rien afficher (option -n
) sauf ce qui est entre les deux RE :
$ sed -n -e "/toto/,/titi/p"
Si on ne veux pas garder les lignes avec les RE :
$ sed -n -e "/toto/,/titi/{//!p}"
En effet, il faut savoir que //
est équivalent aux dernières RE utilisées.
Si on ne veux garder que l’une des bornes (par exemple,
on garde la ligne avec toto
mais on supprime celle avec titi
) :
$ sed -n -e "/toto/,/titi/{/titi/!p}"
Pour joindre toutes les lignes
On peut utiliser sed
(avec N
pour joindre deux lignes, et une boucle),
mais il y a plus simple :
$ tr "\n" ", "
Pour mettre en majuscule
-
la première lettre :
echo salut | sed 's/^./\u&/'
donne :
Salut
-
certaines lettres :
echo "salut les lulus" | sed 's/[sl]/\u&/g'
donne :
SaLut LeS LuLuS
-
toute une expression :
echo "salut les lulus" | sed 's/a[^ ]*/\U&/'
donne :
sALUT les lulus
Documentation
Des liens utiles au sujet de sed
:
Voir aussi :
- Disque dur externe
- Emoticônes et autre binettes
- Garder son PATH dans une commande sudo
- Awk en une ligne
- Perl pour lire un fichier csv
- Vérifier l'intégrité d'un fichier téléchargé
- Bash : faire un menu
- Filtrage de fichiers avec ocaml
- XSLT pour mettre en relation deux documents
- Problème de boot
- Sphinx pour générer une jolie doc en HTML
- Docbook : pour produire de la documentation technique
- Zenity : des fenêtres pour les scripts
- (X)ubuntu : mise à niveau vers la 14.04
- Sqlite en ligne de commande
- Xubuntu: connexion automatique
- Txt2tags
- Apt-get et autres pour la gestion de paquets Debian
- Linux : ramassis d'astuces diverses
- Au sujet des tableurs
- Bash sur la ligne de commande
- Bash : pour écrire des scripts
- LaTeX : pour générer de jolis documents
- Afficher un pourcentage dans une page HTML
- VNC : Virtual Network Computing
- Git : déménagement d'un dépôt
- Quelques liens au sujet de l'analyse statique
- Ocaml: mon principal langage de développement
- Disque dur externe
- Les profiles dans Firefox
- Cryptographie et mail sous Android
- Quelques liens au sujet du C
- Git rebase : pour diviser un commit