J'ai un fichier texte dans ce format:
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Je veux trier ce fichier par KEY
ligne et garder les 4 lignes suivantes avec lui dans le résultat, donc le résultat trié devrait être:
####################################
KEY1
VAL11
VAL12
VAL13
VAL14
####################################
KEY2
VAL21
VAL22
VAL23
VAL24
####################################
KEY3
VAL31
VAL32
VAL33
VAL34
Y a-t-il un moyen de faire cela ?
Réponses:
msort(1)
a été conçu pour pouvoir trier des fichiers avec des enregistrements sur plusieurs lignes. Il a une interface graphique en option, ainsi qu'une version de ligne de commande normale et utilisable pour les humains. (Au 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 soient de taille fixe (en octets, pas en caractères ou en lignes).
msort
a une-b
option pour les enregistrements qui sont des blocs de lignes séparés par des lignes vides.Vous pouvez transformer votre entrée en un format qui fonctionnera
-b
assez facilement, en mettant une ligne vierge avant chaque###...
(sauf la première).Par défaut, il imprime des statistiques sur stderr, donc au moins il est facile de savoir quand il n'a pas été trié car il pensait que l'entrée entière était un seul enregistrement.
msort
travaille sur vos données. Lased
commande ajoute une nouvelle ligne à chaque#+
ligne à l'exception de la ligne 1.-w
trie l'enregistrement entier (lexicographiquement). Il existe des options pour choisir la partie d'un enregistrement à utiliser comme clé, mais je n'en avais pas besoin.J'ai également laissé de côté les nouvelles lignes supplémentaires.
Je n'ai pas eu de chance
-r '#'
de l'utiliser comme séparateur d'enregistrements. Il pensait que le dossier entier était un enregistrement.la source
msort
est très utile; merci (à-r
ce sujet, il semble que ce soit parce qu'il y a plus d'un # que j'ai utilisé-d
et que cela a fonctionnémsort -qwr '#' ex
fonctionne pour moi (eh bien, il modifie le séparateur d'enregistrement de sortie)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 à ramener le séparateur choisi au saut de ligne d'origine:
la source
;N
, et il peut être difficile de trouver un caractère qui n'est pas utilisé dans le texte lui-même; c'est très bon poursort
ouawk
, ... pouvoir faire un tri multiligneperl -0
avale tout le fichier/(....)/g
faire correspondre et extraire les enregistrementsprint sort ...
les trier et les imprimerla source
Voici une autre méthode qui devrait fonctionner avec n'importe quel nombre de lignes dans une
KEY
section:Cela fonctionne en enregistrant le délimiteur dans une variable (pour ensuite le supprimer de l'entrée). Il ajoute ensuite le
KEY*
à chaque ligne dans sa section correspondante en utilisant un caractère ascii faible (qui est peu susceptible de se produire dans votre entrée) comme séparateur, puisn
insère toutes lesl
ines en utilisant le même séparateur. Il ne s'agit alors que desort
passer par les 3ème et 1er champs et decut
ting la colonne du milieu puis de restaurer les délimiteurs via une finalesed
. Notez qu'avec ce qui précède,KEY12
sera trié avantKEY2
afin d'ajuster lasort
commande selon vos besoins.la source
Vous pouvez utiliser la bibliothèque stdlib POSIX Awk :
la source