Comment trouver une ligne avec un motif particulier et en supprimer un nouveau dans unix

Comment trouver une ligne avec un motif particulier et en supprimer les nouveaux caractères dans unix. Supposons que j’ai un fichier séparé par des virgules

100,"John","Clerk",,,, 101,"Dannis","Manager",,,, 102,"Michael","Senior Manager",,,, 103,"Donald","President of united states",,,, 

sortie que je veux est

 100,"John","Clerk",,,, 101,"Dannis","Manager",,,, 102,"Michael","Senior Manager",,,, 103,"Donald","President of united states",,,, 

Solution sed courte:

 sed -z 's/\n*//g; s/,,,,/&\n/g' file 

Le résultat:

 100,"John","Clerk",,,, 101,"Dannis","Manager",,,, 102,"Michael","Senior Manager",,,, 103,"Donald","President of united states",,,, 

Ou avec awk :

 awk 'BEGIN{ RS=ORS="" }{ gsub(/\n+/," ",$0); gsub(/,,,, */,"&\n",$0); print }' file 

essayez de suivre awk trop une fois.

 awk '/^$/{next} {val=$0 ~ /^[0-9]/?(val?val ORS $0:$0):(val?val OFS $0:$0)} END{print val}' Input_file 

EDIT: Ajout d’une forme de solution non-un avec une explication de celui-ci aussi.

 awk ' /^$/{ ## Checking here if a line starts from space, if yes then do following action. next ## next keyword will skip all further actions here. } { val=$0 ~ /^[0-9]/?(val?val ORS $0:$0):(val?val OFS $0:$0) ##creating variable named val here which will check 2 conditions if a line starts with digit then it will concatenate itself with a new line and if a line statrs with non-digit value then it will concatenate its value with a space. } END{ ##END block of awk code here. print val ##printing the value of variable named val here } ' Input_file ## Mentioning Input_file here. 

Cela pourrait fonctionner pour vous (GNU sed):

 sed -r ':a;N;/^([^\n,]*,){6}/!s/\n//;ta;P;D' file 

Ajoutez une autre ligne à l’espace de configuration (PS) et si cette ligne ne contient pas 6, supprimez une nouvelle ligne et répétez, sinon imprimez et supprimez la première des lignes, puis répétez.

si cela ne vous dérange pas avec Perl

Enlevez d’abord la ligne supplémentaire:

 perl -pe 's/^\n//;' file 

le résultat:

 100,"John","Clerk",,,, 101,"Dannis","Manager",,,, 102,"Michael","Senior Manager",,,, 103,"Donald","President of united states",,,, 

alors ce que vous pouvez faire est d’append une nouvelle substitution pour supprimer la nouvelle ligne du dernier mot de chaque ligne. Et pour cela, vous pouvez utiliser:

 s/(\w+)\s+\n$/$1 /; 

ici \w+ correspond à Senior et of et les conserve dans $1 et vous pouvez l’utiliser avec /$1 / et la partie notable est un seul espace: après $1

et enfin nous avons:

 perl -pe 's/^\n//;s/(\w+)\s+\n$/==>$1<== /;' file 

le résultat:

 100,"John","Clerk",,,, 101,"Dannis","Manager",,,, 102,"Michael","==>Senior<== Manager",,,, 103,"Donald","President ==>of<== united states",,,, 

REMARQUE:

supprimer ==> et <== et append -i.bak pour obtenir la sauvegarde et la modification sur place

et même en une seule substitution:

 perl -lpe '$/=undef; s/(\w+)\s+\n\n^([^\n]+)\n/$1 $2/gm;' file 

Copiez le code depuis https://stackoverflow.com/a/45420607/1745001 et modifiez-le:

 { printf "Record %d:\n", ++recNr for (i=1;i<=NF;i++) { printf " $%d=<%s>\n", i, $i } print "----" } 

pour ça:

 /your regexp/ { printf "Record %d:\n", ++recNr for (i=1;i<=NF;i++) { gsub(/\n/," ",$i) printf " $%d=<%s>\n", i, $i } print "----" } 

your regexp est une expression régulière (le “modèle particulier” que vous avez mentionné dans votre question), vous essayez de trouver dans vos données.

Contrairement à la plupart (toutes les?) De vos autres réponses actuelles, ce qui précède ne dépend pas de vos lignes d’entrée se terminant par ,,,, ni ne lit tout le fichier en mémoire. newline commençant par n’importe quelle valeur particulière, et ne se base pas non plus sur une seule ligne vierge dans un champ, ni sur une version particulière d’un outil, etc.

 awk '{printf("%s", $0)}/,,,,/{print "\n"}' ORS="" file 100,"John","Clerk",,,, 101,"Dannis","Manager",,,, 102,"Michael","Senior Manager",,,, 103,"Donald","President of united states",,,,