Linux / Commande csplit : découper un texte par ligne ou par motif

csplit découpe un fichier à un numéro de ligne ou à une ligne correspondant à une expression régulière. Il convient aux documents dont les titres ou marqueurs délimitent les sections. Pour une division par taille ou par nombre fixe de lignes, utilisez plutôt split.

Les fichiers créés portent par défaut des noms comme xx00 et xx01. Choisissez un répertoire d'exercice neuf et un préfixe distinct pour chaque essai. Une sortie portant déjà le même nom peut être remplacée, et les morceaux d'une exécution précédente ne doivent pas être confondus avec les nouveaux.

Préparer les données et comprendre la frontière

csplit [options] entrée motif…

Les exemples concernent GNU csplit dans Bash. Consultez man csplit pour les options de votre système. Préparez un petit fichier dont la ligne centrale servira de frontière :

csplit_lab=$(mktemp -d "$HOME/csplit-lab.XXXXXX")
cd -- "$csplit_lab"
printf 'one\nTWO\ntwo\n' > sample.txt
csplit -s -f part- sample.txt '/^TWO$/'
cat part-00
cat part-01
one
TWO
two

part-00 contient seulement one. part-01 commence par TWO et conserve la suite. Le motif ^TWO$ correspond à une ligne entière, avec cette casse ; ^ marque le début et $ la fin de ligne. Sans décalage supplémentaire, la ligne correspondante commence la section suivante au lieu de terminer la précédente.

-s masque les nombres d'octets que csplit affiche normalement pour chaque morceau créé. Ces nombres ne représentent pas le contenu du fichier. L'entrée sample.txt est conservée. Notez le chemin du répertoire, puis utilisez cd "$HOME" pour quitter l'exercice quand vous avez terminé.

Diviser à un numéro de ligne

Créez quatorze lignes numérotées et placez une frontière avant la ligne 11 :

seq 1 14 > notes.txt
csplit -s -f numbered- notes.txt 11
wc -l numbered-00 numbered-01
cat numbered-01

Le premier morceau contient les dix premières lignes ; le second en contient quatre et affiche 11, 12, 13, 14. Le nombre 11 désigne le numéro de la ligne qui commence le morceau suivant. Il ne demande pas onze lignes dans le premier fichier.

Cette frontière suppose que la ligne existe. Sur un document dont la longueur change, contrôlez le nombre de lignes avant de réutiliser une règle fondée sur une position fixe.

Trouver un titre et répéter le découpage

Préparez un document avec une introduction et deux titres :

printf 'Preface\nChapter 1\nalpha\nChapter 2\nbeta\n' > book.txt
csplit -s -f section- book.txt '/^Chapter /'
cat section-00
cat section-01

Le premier fichier contient Preface. Le second commence par Chapter 1 et contient encore Chapter 2 : un seul argument de motif demande ici une seule frontière. Pour reprendre la même recherche à chaque titre suivant, utilisez la répétition GNU '{*}' :

csplit -s -f chapter- book.txt '/^Chapter /' '{*}'
printf '%s\n' chapter-*
cat chapter-00
cat chapter-01
cat chapter-02

Les noms sont chapter-00, chapter-01 et chapter-02. Ils contiennent respectivement l'introduction, Chapter 1 avec alpha, puis Chapter 2 avec beta. Les apostrophes transmettent le motif et la répétition comme arguments littéraux au programme, sans laisser le shell leur attribuer un autre rôle.

La répétition s'applique au motif précédent. Un nombre entre accolades indique des répétitions supplémentaires ; l'astérisque demande de continuer autant que nécessaire. Testez ces règles sur un échantillon représentatif : un titre absent, une casse différente ou un espace inattendu peut changer les frontières trouvées.

Éviter un premier morceau vide

Lorsque le premier titre se trouve dès la première ligne, tout ce qui le précède forme une section vide. L'option -z permet de ne pas créer ces fichiers vides :

printf 'Chapter 1\nalpha\nChapter 2\nbeta\n' > starts-with-title.txt
csplit -s -z -n 3 -f nonempty- starts-with-title.txt '/^Chapter /' '{*}'
printf '%s\n' nonempty-*
cat nonempty-000
cat nonempty-001

Vous obtenez deux morceaux non vides, nonempty-000 et nonempty-001. -n 3 fixe trois chiffres pour le suffixe. Avec GNU csplit, la numérotation reste consécutive à partir de zéro lorsque les fichiers vides sont écartés.

-z ne retire pas les titres : ils restent au début de leurs sections. Ne confondez pas cette option avec une suppression des lignes de frontière. Certaines règles de csplit peuvent ignorer des portions du texte ; leur reconstruction n'aurait alors plus le même contenu que l'original.

Contrôler une reconstruction et une recherche qui échoue

Dans le découpage chapter de l'exemple, aucune ligne n'a été supprimée. Vous pouvez donc réunir les trois fichiers dans leur ordre :

cat chapter-00 chapter-01 chapter-02 > book-restored.txt
cmp book.txt book-restored.txt

Le contrôle avec cmp doit réussir sans message. Un fichier de sortie doit rester distinct des entrées et ne pas écraser un document à conserver. La simple présence de plusieurs morceaux ne garantit pas que le découpage est complet : vérifiez aussi le statut d'exécution et les frontières de chaque fichier.

Pour observer une erreur en conservant les morceaux de diagnostic, utilisez -k avec un nouveau préfixe et un motif volontairement absent :

csplit -k -s -f failed- sample.txt '/^TWO$/' '/^ABSENT$/'

La première frontière existe, la seconde non. La commande renvoie un statut non nul et un message indiquant l'absence de correspondance. Avec -k, elle garde les sorties déjà produites pour examen ; ces fichiers ne doivent pas être utilisés comme un découpage réussi. Par défaut, sans cette option, GNU csplit retire ses fichiers de sortie créés lorsqu'il rencontre une erreur.

Le fichier source reste disponible. Corrigez le motif, vérifiez le texte attendu et relancez dans un autre répertoire ou avec un préfixe neuf pour distinguer le nouvel essai des résultats partiels.

Options et choix entre split et csplit

Option ou forme Rôle
-f préfixe Choisir le début des noms de sortie.
-n N Choisir le nombre de chiffres des suffixes.
-s Masquer les comptes d'octets affichés après création.
-z Ne pas produire de morceaux vides.
-k Conserver les sorties déjà créées en cas d'erreur.
/motif/ Créer une frontière avant une ligne qui correspond à l'expression régulière.
'{*}' Avec GNU csplit, répéter le motif précédent jusqu'à épuisement des frontières.

Choisissez split si l'unité est une quantité d'octets ou de lignes. Choisissez csplit si l'unité est un titre, un marqueur ou une position précise dans le texte. Le manuel officiel de GNU csplit décrit les motifs, les décalages et les options qui influencent le contenu conservé.