Trucs de geek : La commande cut (couper)

Les admins mais aussi les utilisateurs avertis de Linux sont souvent amenés à écrire des scripts bash. Cela permet d'automatiser des ensembles de commandes. Une planification avec cron permettra ensuite de les exécuter automatiquement. Ces scripts regroupent de nombreuses commandes awk, sed, tr, cut. Cette dernière commande fait objet de cet article.

Ces scripts font donc appel à des commandes bash. Nous avons déja vu cat, nl et wc, sort ou grep.

Cette nouvelle commande "cut" (couper en anglais) permet de

  • sélectionner des parties continues des lignes d'un fichier texte,
  • sélectionner des zones dans les lignes d'un fichier texte, sachant que ces zones sont identifiées par des séparateurs.

Soit le fichier servant d'exemple :

abcdefghijklmnopqrstuvwxyz
bcdefghijklmnopqrstuvwxyza
cdefghijklmnopqrstuvwxyzab
defghijklmnopqrstuvwxyzabc

Pour n'afficher que le deuxiéme caractère de chaque ligne :

$ cut -c 2 test.txt

donne

b
c
d
e

Pour afficher les colonnes 2 à 5 :

$ cut -c 1-5 test.txt

donne

abcde
bcdef
cdefg
defgh

Pour couper le début des lignes à partir d'une position donnée :

$ cut -c 3- test.txt

donne

cdefghijklmnopqrstuvwxyz
defghijklmnopqrstuvwxyza
efghijklmnopqrstuvwxyzab
fghijklmnopqrstuvwxyzabc

Pour ne conserver que les premiers caractères de chaque ligne :

$ cut -c -8 test.txt

donne

abcdefgh
bcdefghi
cdefghij
defghijk

En combinant les options -d et -f vous pouvez extraire des champs entiers au lieu de suite de caractères. Si nous souhaitons obtenir la liste des utilisateurs de notre machine, nous devons extraire le premier champ du fichier /etc/passwd :

$ cut -d':' -f1 /etc/passwd

Chaque ligne est éclatée en différent champs délimités par des deux points verticaux. Cela donne :

root
daemon
bin
sys
...
jfd
sshd
libvirt-qemu
libvirt-dnsmasq
gdm
hsqldb
postfix
dnsmasq

On peut réaliser une sélection de lignes dans un fichier et l'envoyer à cut pour en extraire certains champs :

$ grep "/bin/bash" /etc/passwd

permet de n'afficher que les utilisateurs dont le shell par défaut est bash. A partir de cette sélection on va extraire le nom de l'utilisateur (champ 1) et son répertoire home (champ 6) :

$ grep "/bin/bash" /etc/passwd | cut -d':' -f 1,6

qui donne :

root:/root
jfd:/home/jfd
hsqldb:/var/lib/hsqldb

Il est possible de ne pas afficher un champ dans la ligne :

$ grep "/bin/bash" /etc/passwd | cut -d':' --complement -s -f

donnera :

root:x:0:0:root:/root
jfd:x:1000:1000:JF Digonnet,,,:/home/jfd
hsqldb:x:115:131:HSQLDB system user,,,:/var/lib/hsqldb

On n'affiche pas le shell par défaut des utilisateurs (champ no 7).

On peut ajouter un séparateur entre les champs affichés :

$ grep "/bin/bash" /etc/passwd | cut -d':' -f 1,6 --output-delimiter=' # '

donne

root # /root
jfd # /home/jfd
hsqldb # /var/lib/hsqldb

Pour créer un retour à la ligne pour chaque champ on ajoute  "--output-delimiter=$'\n '" et pour une tabulation, on ajoute "--output-delimiter=$'\t'".

Fait le 01/02/2016