4 votes

Créer un csv à partir d'un fichier texte incohérent

J'ai des enregistrements vaguement structurés dans un fichier composé de 3 ou 4 lignes de texte séparées (la plupart du temps) par une ligne blanche. Tous les enregistrements n'ont pas un séparateur de ligne vide, mais la dernière ligne de chacun d'eux commence par le mot "Added". Je voudrais produire un fichier csv avec chaque enregistrement sur une ligne précédé de son numéro de ligne. Jusqu'à présent, je n'ai pu produire qu'une concaténation de tous les enregistrements séparés par un nombre arbitraire d'espaces et une virgule redondante.

Logiquement, j'essaie d'obtenir ce qui suit :

Lire la ligne, si la ligne commence par 'Added', garder la nouvelle ligne à la fin.
sinon, remplacez 'newline' par ','.
ou si la ligne est vide, la supprimer
endif

Les données de l'échantillon :

Peter Green  
Space Monkey at Area 51  
Joined  
Added by SF 3 weeks ago  
Will Rossiter  
Joined  
Added by SF 3 weeks ago

Dean Matthews  
Guitarist at Blues  
Joined  
Added by SF 3 weeks ago  
Hobbit Mak  
Farnborough, United Kingdom  
Joined  
Added by SF 3 weeks ago  

Keneth W Moorfield  
THE STOREMAN  
Joined  
Added by SF 3 weeks ago  
Mick Georgious  
Software Engineer  
Joined  
Added by SF 3 weeks ago

5voto

user221266 Points 11

Essayez :

awk '/./{ printf "%s%s", $0, (/Added/?"\n":",") }' data

En utilisant vos données d'entrée types :

$ awk '/./{printf "%s%s",$0,(/Added/?"\n":",")}' data
Peter Green,Space Monkey at Area 51,Joined,Added by SF 3 weeks ago
Will Rossiter,Joined,Added by SF 3 weeks ago
Dean Matthews,Guitarist at Blues,Joined,Added by SF 3 weeks ago
Hobbit Mak,Farnborough, United Kingdom,Joined,Added by SF 3 weeks ago
Keneth W Moorfield,THE STOREMAN,Joined,Added by SF 3 weeks ago
Mick Georgious,Software Engineer,Joined,Added by SF 3 weeks ago

Comment cela fonctionne :

  • /./{...}

    Cette commande exécute les commandes entre accolades uniquement si la ligne contient un caractère. En d'autres termes, cette commande ignore les lignes vides.

  • printf "%s%s",$0,(/Added/?"\n":",")

    Cela imprime la ligne, désignée par $0 suivi d'une virgule ou d'un saut de ligne, selon que la ligne correspond ou non à la règle d'exclusion. Added .

3voto

steeldriver Points 118154

Voici une possibilité sed (avec awk faire la numérotation des lignes) :

$ sed -n -e :a -e '$!{/^$/!N}; /,Added/ {P;D}; s/\n/,/; ta' data | awk '{print NR","$0}'
1,Peter Green,Space Monkey at Area 51,Joined,Added by SF 3 weeks ago
2,Will Rossiter,Joined,Added by SF 3 weeks ago
3,Dean Matthews,Guitarist at Blues,Joined,Added by SF 3 weeks ago
4,Hobbit Mak,Farnborough, United Kingdom,Joined,Added by SF 3 weeks ago
5,Keneth W Moorfield,THE STOREMAN,Joined,Added by SF 3 weeks ago
6,Mick Georgious,Software Engineer,Joined,Added by SF 3 weeks ago 

En gros, nous continuons à ajouter des lignes d'entrée non vides et à remplacer les nouvelles lignes par des virgules, sauf que nous vérifions à chaque itération si nous avons un enregistrement complet et si c'est le cas, nous le recrachons, par exemple

  • définir une étiquette de programme :a
  • si elle n'est pas à la fin du fichier $! puis ajoutez les lignes non vides à l'espace du motif {/^$/!N}
  • si nous sommes à la fin d'un enregistrement /,Added/ puis l'imprimer P et le supprimer D de l'espace des motifs
  • remplacer la virgule par un saut de ligne s/,/\n/ en se ramifiant vers a sur le succès

2voto

steeldriver Points 118154

Pour info, voici un perl option :

$ perl -lne '
    push @rec, $_ unless /^$/; if (/^Added/) {print join ",", ++$n, @rec; undef @rec;}
' data
1,Peter Green,Space Monkey at Area 51,Joined,Added by SF 3 weeks ago
2,Will Rossiter,Joined,Added by SF 3 weeks ago
3,Dean Matthews,Guitarist at Blues,Joined,Added by SF 3 weeks ago
4,Hobbit Mak,Farnborough, United Kingdom,Joined,Added by SF 3 weeks ago
5,Keneth W Moorfield,THE STOREMAN,Joined,Added by SF 3 weeks ago
6,Mick Georgious,Software Engineer,Joined,Added by SF 3 weeks ago

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X