-2
votes

Joindre entre deux modèles

J'ai cherché une réponse à cela, mais je ne trouve pas ce qui fonctionne. C'est ce que j'essaye d'accomplir. Dans un fichier, j'ai des lignes qui commencent par un motif spécifique et parfois il y a une ligne entre elles et d'autres fois il n'y en a pas. J'essaye de joindre la ligne entre les modèles à la première ligne de modèle. Exemple ci-dessous:

Sortie courant:

Name: Doe John Some Random String  
Mailing Address: 1234 Street Any Town, USA    

Remarque: la ligne "Some Random String" n'existe parfois pas, la jointure n'est donc pas nécessaire

Sortie désirée:

Name: Doe John   
Some Random String  
Mailing Address: 1234 Street Any Town, USA  

J'ai essayé les réponses sed et awk que j'ai trouvées sur le net, mais je ne peux pas comprendre comment faire fonctionner cela. Mes compétences sed et awk sont très basiques à ce stade, donc je ne comprends pas très bien certaines des solutions même lorsqu'elles sont expliquées.

Merci pour toute aide ou un point sur la documentation qui parle de ce que j'essaie d'accomplir.


2 commentaires

Bien que vous ayez mentionné que vous avez regardé autour des forums, veuillez faire ces efforts / codes dans votre question également, il n'y a pas de bien ou de mal ici car nous sommes tous pour apprendre, ajouter des efforts dans les questions est fortement encouragé sur SO, bravo.


Votre fichier ne contient toujours que deux ou trois lignes?


4 Réponses :


3
votes

Pourriez-vous s'il vous plaît essayer de suivre, écrit et testé avec les exemples présentés dans GNU awk .

awk  '        ##Starting awk program from here.    
{
  printf("%s%s",FNR>1 && ($0~/^Mailing/ || $0 ~/Name:/)?ORS:OFS,$0)
              ##Using printf to print strings, 1st one is either newline or space, which is based on
              ##condition if line is greater than 1 OR line is either starts with Mailing or has Name
              ##Then print ORS(newline) or print OFS(space). For 2nd string print current line.
}
END{          ##Starting END block of this program from here.
  print ""    ##Printing new line here.
}
' Input_file  ##Mentioning Input_file name here.

OU si vous souhaitez mettre de nouvelles lignes uniquement pour les deux chaînes Name et Mailing essayez de suivre.

awk  '
{
  printf("%s%s",FNR>1 && ($0~/^Mailing/ || $0 ~/Name:/)?ORS:OFS,$0)
}
END{
  print ""
}
' Input_file

Explication: Ajout d'une explication détaillée ci-dessus.

awk  '{printf("%s%s",FNR>1 && $0~/^Mailing/?ORS:OFS,$0)} END{print ""}' Input_file


1 commentaires

Très belle réponse avec une explication complète!



1
votes

Un autre awk où vous définissez les modèles spécifiques :

Name: Doe John   Some Random String  
Mailing Address: 1234 Street Any Town, USA  Using: but not specific pattern

Sortie sur des données légèrement modifiées (l'espace supplémentaire provient de vos données, ne les a pas coupées):

$ awk '
BEGIN {
    p["Name"]              # define the specific patters that start the record
    p["Mailing Address"]
}
{
    printf "%s%s",(split($0,t,":")>1&&(t[1] in p)&&NR>1?ORS:""),$0
}
END {
    print ""               # conditional operator controls the ORS so needed here 
}' file


0 commentaires

1
votes

Que diriez-vous d'une solution GNU sed :

sed '
/^Name:/{                               ;# if the line starts with "Name:" enter the block
N                                       ;# read the next line and append to the pattern space
:l1                                     ;# define a label "l1"
/\nMailing Address:/! {N; s/\n//; b l1} ;# if the next line does not start with "Mailing Address:"
                                        ;# then append next line, remove newline and goto label "l1"
}' file


0 commentaires

0
votes

Cela pourrait fonctionner pour vous (GNU sed):

sed '/Name:/{:a;N;/Mailing Address:/!s/\s*\n\s*/ /;$!ta}' file

Si une ligne contient Name: continuez d'ajouter des lignes et de remplacer l'espace blanc de chaque côté de la nouvelle ligne par un espace, jusqu'à la fin du fichier ou une ligne contenant l' Mailing Address:


0 commentaires