LinuxPedia

Wiki libre et indépendant dédié à GNU-Linux et BSD.

Outils pour utilisateurs

Outils du site


commande:cat

"cat", lire, écrire, concaténer du texte

“cat” est une de ces commandes incontournables, elle sert le plus souvent à lire un contenu textuel, mais elle peut faire plus. Son nom est dérivé de l'Anglais “concatenate”, “concaténer” en Français.

Un signe $ précède les commandes qui ne nécessitent pas de droits administrateur ; un signe # précède celles qui nécessitent des droits administrateur (ces signes ne font PAS partie des commandes). Les lignes qui ne commencent pas par un signe $ ou # correspondent au résultat de la commande précédente.
Les touches utilisées sont indiquées entre crochets, exemple [ctrl] pour la touche “contrôle”

Lire un fichier en console

“cat” est adapté à la lecture d'un fichier court, son utilisation de base est très simple :

$ cat /home/tux/test.txt
blabla, ceci est un test.

Nous venons de lire le fichier “test.txt” dans le répertoire personnel de l'utilisateur “tux”, rien de difficile. Maintenant nous voulons lire deux fichiers “test.txt” et “test2.txt” qui se trouvent dans le répertoire courant :

$ cat test.txt test2.txt
blabla, ceci et un test.
Et voici un deuxième fichier de test.

Ça paraît clair, par défaut “cat” écrit le(s) fichier(s) demandé(s) sur la sortie standard (l'indicateur de la sortie standard, le symbole “-”, est implicitement supposé si aucune autre sortie n'est indiquée.).

“cat” peut appliquer quelques traitements simples au texte, comme par exemple numéroter toutes les lignes (option “-n”), ou seulement les lignes qui contiennent effectivement du texte (option “-b”). On peut également supprimer les lignes vides successives pour n'en laisser qu'une seule (option “-s”), ou afficher tous les caractères non-imprimables, tabulations et fins de lignes avec “-A”.

Appliquer ce type de traitements est surtout intéressant lorsqu'on écrit le résultat dans un nouveau fichiers.

Écrire et concaténer (réunir) des fichiers

“cat” ne sait pas “écrire” à proprement parler, mais pour arriver au même résultat il suffit de rediriger le résultat d'une commande vers un fichier texte :

$ cat test.txt
blabla, ceci et un test.
$ cat test2.txt
Et voici un deuxième fichier de test.

$ cat -n test.txt test2.txt > test3.txt
$ cat test3.txt
1 blabla, ceci et un test.
2 Et voici un deuxième fichier de test.

Nous venons de réunir les fichiers “test.txt” et “test2.txt”, en ajoutant la numérotation des lignes, dans un fichier “test3.txt”.
La redirection n'est pas propre à “cat”, elle fonctionne de la même façon pour tous les programmes en ligne de commande.

Symbole de redirection Usage
> fichier Crée le fichier s'il n'existe pas, remplace son contenu s'il existe
>> fichier Crée le fichier s'il n'existe pas, ajoute à la fin du fichier s'il existe

:!: Il est essentiel de bien comprendre qu'avec “>” vous remplacez, et donc détruisez, l'ancien contenu du fichier cible si celui-ci existe déjà.

Maintenant admettons que l'on veuille écrire du texte dans un nouveau fichier, mais que ce texte n'existe pas encore. Nous allons indiquer à “cat” de prendre en compte le texte tapé jusqu'à un certain signal, et de l'écrire dans un fichier texte :

$ cat << FIN >> test4.txt
>Je veux écrire du texte dans un fichier
>Ça je voudrais bien \
>que ça tienne sur une ligne.
>
>Simple !
>FIN

Attention, il y a un piège, le signe “>” en début de chaque ligne qui suit la commande indique simplement une invite de commande, c'est un symbole qui indique que “cat” “attend” que vous écriviez quelque chose. Ce signe “>” n'est pas à taper, et il n'apparaît pas dans le résultat.

Bon, et ça donne quoi ?

$ cat test4.txt
Je veux écrire du texte dans un fichier
Ça je voudrais bien que ça tienne sur une ligne.

Simple !

Quelques explications, le texte est rendu tel quel, chaque appui sur la touche [entrée] entraîne un saut de ligne, sauf si la ligne se termine par un antislash “\”. Si la ligne est laissée vide cela donne une ligne vide.
Le mot “FIN” n'est pas écrit dans le fichier, c'est notre marqueur de fin de fichier défini dans la commande. On peut utiliser n'importe quel mot comme marqueur, par convention on trouvera souvent “EOF” qui signifie “End Of File” (“fin de fichier” en Anglais).

Trop facile “cat” ? Amusons nous un peu alors ! Que ce passe-t-il avec du texte un peu “spécial”, comme des commandes, des variables ou des caractères spéciaux ?

$ cat <<- EOF
>Ceci est un test
>si on met une commande ça fait quoi ?
>who
>et comme ça ?
>`who`
>Hoo, et alors avec ça ?
>$(uname -r)
>"$(uname -r)"
>Mais je veux juste l'écrire, pas l'exécuter !
>\$(uname -r)
>C'est mieux, quel bazar.
>* $ ^
>Tiens, ça ne fait rien avec les caractères spéciaux...
>Bon, ça suffit pour le moment.
>EOF

Nous avons changé la commande, ici nous redirigeons le texte simplement vers la sortie standard, soit la console, avec le symbole “-”. Nous avons choisi “EOF” comme marqueur de fin de fichier. Le résultat :

Ceci est un test
si on met une commande ça fait quoi ?
who
et comme ça ?
tux :0           2009-06-17 07:23
Hoo, et alors avec ça ?
2.6.29.5-vanilla64
"2.6.29.5-vanilla64"
Mais je veux juste l'écrire, pas l'exécuter !
$(uname -r)
C'est mieux, quel bazar.
* $ ^
Tiens, ça ne fait rien avec les caractères spéciaux...
Bon, ça suffit pour le moment.

On voit qu'il faut prendre quelques précautions, les commandes gardent leur valeur littérale, sauf si on indique au shell de les évaluer avec des “backticks” “`” (cas du deuxième “who”). Pour les variables c'est plus compliqué, elles sont évaluées même si elles sont encadrées par des guillemets simples ou doubles (qui gardent leur valeur littérale ici). Pour préserver la valeur littérale d'une variable il faut donc l'échapper avec un antislash “\”, par exemple “\$PATH” pour écrire “$PATH” et non obtenir la valeur de la variable.
Mmm, il n'y a pas plus simple pour taper du texte et préserver les variables ? Si, il suffit d'utiliser “cat” de cette manière :

$ cat > test.txt
Je tape mon texte.
Cette fois les variables \
seront préservées.
$PATH
Les commandes aussi
`who`
$(uname -r)

Pour terminer la séquence utilisez les touches [ctrl] [d], cette fois-ci les lignes ne commencent pas par le signe “>”, il ne s'agit plus d'invites de commandes. Tout le texte garde sa valeur littérale. Le résultat :

$ cat test.txt
Je tape mon texte.
Cette fois les variables \
seront préservées.
$PATH
Les commandes aussi
`who`
$(uname -r)

Tout est préservé.

"cat" est-il vraiment utile ?

Oui ! (Ouf), mais finalement pas si souvent. Voici les cas typiques où l'emploi de “cat” est une mauvaise idée :

  • Lire un long fichier de journal (log), on utilisera plutôt un pager comme “less” ou “most” qui rend la lecture plus confortable, ou “head”/“tail” pour ne lire que le début/la fin du fichier.
  • Redirection vers “grep” pour chercher une expression. C'est une lourdeur inutile, on peut utiliser “grep” directement sur des fichiers textes, pas besoin de passer par “cat” et une redirection.
  • Pour des fichier binaires, “cat” ne vous renseignera pas beaucoup, pour rechercher du texte “compréhensible” dans une archive binaire il faut utiliser “strings” par exemple.

En revanche “cat” peut être utile là où ne l'attend pas, par exemple pour mettre bout-à-bout deux archives vidéo ou images “.iso”. Pour que cela fonctionne il faut que les vidéos aient les mêmes propriétés (format, débit, encodage …), et que les vidéos ou les images “.iso” aient été au préalable coupées volontairement. Un exemple avec une image “.iso”

$ split --bytes=50M pmagic-4.2.iso
$ ls
pmagic-4.2.iso xaa  xab
$ cat xaa xab > pmagic-4.2_2.iso
$ md5sum pmagic-4.2.iso
8a1ad4e84cae8fe1d1e230cdc8ec1bd2  pmagic-4.2.iso
$ md5sum pmagic-4.2_2.iso
8a1ad4e84cae8fe1d1e230cdc8ec1bd2  pmagic-4.2_2.iso

Nous avons une image “.iso” de 95Mo, nous la coupons en deux avec la commande “split”, en précisant une taille maximale pour les parties de 50Mo (option “--bytes=”). Cela revient à produire deux fichiers “xaa” et “xab” (ce type de noms est le défaut de la commande “split”, voir “man split”).
Avec “cat” nous réunissons à nouveau ces deux parties en une image “.iso”, nous changeons le nom de l'image pour ne pas écraser l'originale qui se trouve dans le même répertoire.
Pour vérifier que l'opération n'a pas altérée l'image nous exécutons une somme de contrôle “md5” sur l'image originale, et celle produite par “split” puis “cat” : ce sont bien les mêmes.

La même opération fonctionne parfaitement avec une vidéo, on peut la découper en nombreux petits morceaux avec “split”, et la reconstituer avec “cat”.

$ split --bytes=1M lion.ogv
$ ls
lion.ogv  xaa  xab  xac  xad
$ cat xaa xab xac xad > lion2.ogv

La video résultante “lion2.ogv” est exactement la même que l'originale “lion.ogv”, le lecteur video “VLC” la lira aussi bien.

Pratique pour envoyer de gros fichiers.

Vous préférez les chiens aux les chats ?

“cat” en Anglais signifie “chat”, alors quand un développeur a l'idée de créer une version “améliorée” de “cat” il la nomme naturellement “dog” (“chien” en Anglais)… “dog” est présent dans les dépôts de quelques distributions, dont Debian. Si vous êtes curieux vous irez faire un tour dans son manuel pour voir les différences avec “cat”. “dog” n'étant pas une commande standardisée elle est d'un usage anecdotique, et sera à éviter absolument dans des scripts par exemple (pour des raisons de portabilité). “dog” possède de nombreuses options supplémentaires, peut travailler sur des url. Un extrait du manuel pour le plaisir de la rubrique “NAME” :

DOG(1)                              User Manuals                                    DOG(1)

NAME
       dog - better than cat

SYNOPSIS
       dog  [-AbBeEnstTuv]  [-w[cols]]  [-l lines] [--show-all] [--number-nonblank] [--no-blanks] [--bind=port] [--dos]
       [--show-ends] [--hang-up] [--images] [--links]  [--lower]  [--mac]  [--number]  [--no-header]  [--squeeze-blank]
       [--sock=domain:port]  [--sock-test]  [--show-tabs]  [--raw]  [--rot=num] [--udp] [--unix] [--upper] [--show-non‐
       printing] [--hide-nonprinting] [--help] [--hex] [--skip-tags] [--version] file | URL | - ...

DESCRIPTION
       dog writes the contents of each given file, URL, or the standard input if none are given or when  a  file  named
       ’-’ is given, to the standard output. It currently supports the file, http, and raw URL types. It is designed as
       a compatible, but enhanced, replacement of cat(1).
[...]

Amusez vous bien ! ;-)


commande/cat.txt · Dernière modification: 2018/11/17 12:52 (modification externe)