Comment lire les valeurs séparées par des virgules

Nous avons un fichier de largeur fixe

Col1 length 10 Col2 length 10 Col3 length 30 Col4 length 40 

Exemple d’enregistrement

 ABC 123 xyz. 5171-5261,51617 ABC. 1234. Xxy. 81651-61761 

Col4 peut avoir un nombre quelconque de valeurs séparées par des virgules 1 ou plus dans la longueur de 40 caractères:
S’il a 1 valeur pour cet enregistrement, il n’y a pas de changement dans le fichier de sortie. Si plusieurs valeurs sont présentes, c’est-à-dire séparées par des virgules (5171-5261,51617), le fichier de sortie doit avoir plusieurs enregistrements.

 1 record ABC. 123. Xyz. 5171-5261 ABC 123. Xyz. 51617 

Quelle est la manière la plus efficace de le faire? A partir de maintenant, essayez d’utiliser while et for loop, mais cela prend beaucoup de temps pour l’exécution car nous faisons ce fractionnement en lisant chaque enregistrement.

Le fichier de sortie peut être séparé par une virgule ou une largeur fixe.

awk est ton ami ici.

Une seule ligne de awk atteindra ce dont vous avez besoin:

 awk -v FIELDWIDTHS="10 10 30 40" '{ if (match($4,",")) { split($4,array,","); for (i in array) { print $1,$2,$3,array[i]; }; } else { print $1,$2,$3,$4 }; }' samp.dat 

Pour faciliter la lecture, le code est le suivant:

 { if (match($4,",")) { split($4,array,","); for (i in array) { print $1,$2,$3,array[i]; }; } else { print $1,$2,$3,$4 }; } 

Le test avec les exemples de données que vous avez fournis donne:

 ABC 123 xyz. 5171-5261 ABC 123 xyz. 51617 ABC. 1234. Xxy. 81651-61761 

Comment ça marche:
awk lit votre fichier une ligne à la fois.
La directive FIELDWIDTHS nous permet de référencer chaque colonne comme $1,$2...
Maintenant que nous avons nos colonnes, nous pouvons rechercher une virgule dans le quasortingème champ avec une match($4,",") .
Si nous en trouvons un, nous faisons un tableau des valeurs du quasortingème champ qui sont séparées par des virgules avec split($4,array,",") .
Ensuite, nous parcourons ce tableau et imprimons plusieurs lignes de sortie, une pour chaque élément du tableau.
Si le quasortingème champ n’a pas de virgule, la clause else imprime une seule ligne.
Ce processus se répète pour chaque ligne de votre fichier à largeur fixe.

REMARQUE: les tableaux associatifs awk ne garantissent pas la préservation de l’ordre de vos données. Cela signifie que votre sortie pourrait sortir comme

 ABC 123 xyz. 51617 ABC 123 xyz. 5171-5261 ABC. 1234. Xxy. 81651-61761 

à savoir 5171-5261,51617 dans les données d’entrée produit une ligne à partir de la deuxième valeur avant la première.

Si la commande est importante pour vous, vous pouvez utiliser le code ci-dessous qui crée d’abord un fichier CSV à partir de vos données d’entrée, puis produit la sortie en préservant la commande.

 awk -v FIELDWIDTHS="10 10 30 40" '{print $1,$2,$3,$4}' OFS=',' samp.data > samp.csv awk -F',' '{ for (i=4; i<=NF; i++) { print $1,$2,$3,$i } }' samp.csv