GNU/Linux >> Tutoriels Linux >  >> Linux

Trier les fichiers texte avec plusieurs lignes sur une ligne

msort(1) a été conçu pour être en mesure de trier les fichiers avec des enregistrements multi-lignes. Il a une interface graphique facultative, ainsi qu'une version de ligne de commande normale et utilisable pour les humains. (Du moins, les humains qui aiment lire attentivement les manuels et chercher des exemples...)

AFAICT, vous ne pouvez pas utiliser un modèle arbitraire pour les enregistrements, donc à moins que vos enregistrements ne soient de taille fixe (en octets, pas en caractères ou en lignes). msort a un -b option pour les enregistrements qui sont des blocs de lignes séparés par des lignes vides.

Vous pouvez transformer votre entrée dans un format qui fonctionnera avec -b assez facilement, en mettant une ligne vide avant chaque ###... (sauf le premier).

Par défaut, il imprime des statistiques sur stderr, donc au moins il est facile de dire quand il n'a pas trié parce qu'il pensait que toute l'entrée était un seul enregistrement.

msort fonctionne sur vos données. Le sed la commande ajoute une nouvelle ligne à chaque #+ ligne sauf la ligne 1. -w trie l'intégralité de l'enregistrement (lexicographiquement). Il existe des options pour choisir quelle partie d'un enregistrement utiliser comme clé, mais je n'en ai pas eu besoin.

J'ai également laissé de côté la suppression des retours à la ligne supplémentaires.

$ sed '2,$ s/^#\+/\n&/' unsorted.records | msort -b -w 2>/dev/null 
####################################
KEY1
VAL11
VAL12
VAL13
VAL14

####################################
KEY2
VAL21
VAL22
VAL23
VAL24

####################################
KEY3
VAL31
VAL32
VAL33
VAL34

Je n'ai pas eu de chance avec -r '#' pour l'utiliser comme séparateur d'enregistrements. Il pensait que le fichier entier était un seul enregistrement.


Une solution consiste à remplacer d'abord les sauts de ligne à l'intérieur d'un bloc par un caractère inutilisé de votre choix ('|' dans l'exemple ci-dessous), à trier le résultat et à remplacer le séparateur choisi par le saut de ligne d'origine :

sed -e 'N; N; N; N; N; s/\n/|/g' file.txt \
| sort -k2,2 -t\| \
| sed 's/|/\n/g'

perl -0ne 'print sort /(#+[^#]*)/g' file.txt
  • perl -0 avale tout le fichier
  • /(....)/g faire correspondre et extraire les enregistrements
  • print sort ... triez-les et imprimez-les

Linux
  1. Ventoy :Comment créer une clé USB multiboot avec plusieurs fichiers ISO

  2. Comment trouver des fichiers volumineux Linux avec les commandes find et du

  3. Comment supprimer plusieurs lignes aléatoires d'un fichier texte à l'aide de Sed ?

  4. Trier les fichiers dans un dossier spécifique avec Ranger ?

  5. Dd :plusieurs fichiers d'entrée ?

Awk one-liners et scripts pour vous aider à trier les fichiers texte

Synchroniser des fichiers entre plusieurs systèmes avec Syncthing

Dupliquer, avec quelques petites modifications, quelques lignes dans un fichier texte ?

Remplacer plusieurs textes de fichiers par Sed ?

Joindre plusieurs champs dans des fichiers texte sous Unix

Fusionner des fichiers pdf avec un tri numérique