Réorganiser le fichier texte en fonction des correspondances dans les colonnes

Je travaille avec un dataset:

ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4 BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8 GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1 GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1 GOB S 18:01:13.638 -0.6 IML Pg 18:00:52.264 -0.6 

En utilisant AWK et moi-même, les lignes qui correspondent doivent être imprimées sur la même ligne.

c’est à dire

 ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4 BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8 

J’ai essayé toutes sortes d’idées différentes, mais je n’arrive pas à localiser le code pour le faire. J’ai essayé d’utiliser AWK, comme demandé par mon supérieur. Serait intéressé de voir si ce serait plus facile en Python?

(notez un espace blanc entre les lignes pour préserver la structure)

Si je comprends bien, vous correspondez au premier champ et le fichier est sortingé. Dans ce cas, essayez:

 $ awk 'NR>1{printf "%s%s",($1==last?" ":"\n"),$0}; NR==1{printf "%s",$0} {last=$1} END{print""}' file ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4 BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8 GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1 GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1 GOB S 18:01:13.638 -0.6 IML Pg 18:00:52.264 -0.6 

Comment ça marche

  • NR==1{printf "%s",$0}

    Pour la première ligne, nous l’imprimons sans nouvelle ligne de fin.

  • NR>1{printf "%s%s",($1==last?" ":"\n"),$0}

    Pour les lignes après la première, nous imprimons un espace si les premiers champs correspondent ou une nouvelle ligne s’ils ne le sont pas, suivis de la ligne.

    La partie la plus délicate est l’instruction ternaire $1==last?" ":"\n" . Cela ne fait que tester si le premier champ est égal au dernier premier champ. Si c’est le cas, il retourne la chaîne après le ? . Si ce n’est pas le cas, il retourne la chaîne après le :

  • last=$1

    Nous mettons à jour la variable en last dans le premier champ le plus récent.

  • END{print""}

    Après avoir fini de lire le fichier et de nous assurer que nous avons une ligne finale complète, nous imprimons une nouvelle ligne.

un autre awk

 $ awk '{a[$1]=a[$1]?a[$1] FS $0:$0} END{for(k in a) print a[k] | "sort" }' file | column -t ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4 BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8 GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1 GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1 GOB S 18:01:13.638 -0.6 IML Pg 18:00:52.264 -0.6 

accumuler des enregistrements avec la même clé, imprimer à la fin et sortinger (à l’aide de la clé), la column pour obtenir un rendu agréable. Ne nécessite pas que les clés soient contiguës ou sortingées.

Cela pourrait être abordé en Python comme suit:

 from itertools import groupby data = """ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4 BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8 GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1 GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1 GOB S 18:01:13.638 -0.6 IML Pg 18:00:52.264 -0.6""" print '\n'.join(' '.join(g) for k,g in groupby(data.splitlines(), key=lambda x: x.split()[0])) 

Cela afficherait:

 ALI P 18:00:40.583 0.0 ALI S 18:00:58.188 1.4 BRD Pg 18:00:48.918 0.4 BRD Sg 18:01:09.437 -1.8 GAN Pn 18:00:58.207 -0.0 GAN Sn 18:01:27.791 0.1 GLB P 18:00:27.265 -0.4 GLB S 18:00:34.187 0.1 GOB S 18:01:13.638 -0.6 IML Pg 18:00:52.264 -0.6