Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1648 connectés 

  FORUM HardWare.fr
  Programmation
  Shell/Batch

  [Shell/Batch] Modification de valeurs non numériques dans une colonne

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Shell/Batch] Modification de valeurs non numériques dans une colonne

n°2042344
aircamus
Posté le 15-12-2010 à 14:29:59  profilanswer
 

Bonjour à tous,
 
J’ai un petit problème sur lequel je bloque. Je souhaite pouvoir remplacer dans un fichier csv le champ d’une certaine colonne, par une valeur numérique fixe, lorsque celui-ci contient une valeur non numérique (càd avec au moins un caractère non compris entre [0-9]).  
 
Par exemple, si j’ai le fichier csv suivant :
 
A0001;B32;00000G1;20101010
A000201;B30;0000021;20101210
A0001;B3421;0000022;20101210
A0011103;B30;0000F22;20101210
A0001;B30;0000023;20101210
 
Je voudrais remplacer toutes les valeurs de la troisième colonne qui ne sont pas numériques par « 9999999999 » pour obtenir le fichier csv suivant :
 
A0001;B32;9999999999;20101010
A000201;B30;0000021;20101210
A0001;B3421;0000022;20101210
A0011103;B30;9999999999;20101210
A0001;B30;0000023;20101210
 
Cela est-il possible via awk ou sed ou tout autre outil et si oui quelle est alors la regexp ou l'instruction à utiliser ?
 
Merci d’avance pour vos solutions

mood
Publicité
Posté le 15-12-2010 à 14:29:59  profilanswer
 

n°2042409
olivthill
Posté le 15-12-2010 à 16:08:10  profilanswer
 

Via une regexp, c'est sans doute possible, mais ce sera un peu compliqué.
 
Par contre, par awk, il est possible de le faire avec des if traditionnels assez simples.
 
Par exemple, il faudrait utiliser awk en lui indiquant que le séparateur est le point virgule (on supposera qu'il n'y a pas de point virgule à l'intérieur d'une chaine de caractères, mais que tous les points virgules sont des séparateurs de champs). Cela se fait, soit avec l'option -F, soit avec le mot clé FS de awk. Ensuite, il suffit de tester $3, puisqu'il s'agit de la troisième colonne, et de la laisser telle quelle ou de la changer.

n°2042431
Nukolau
Posté le 15-12-2010 à 16:52:55  profilanswer
 

C'est pas forcément compliqué via une regex, et que tu sois en awk ou pas, tu es tout de même obligé d'y passer ;)

 

sans awk, tu peux faire un test comme ca :

Code :
  1. [ $(echo $line | awk -F';' '{print $3}' | grep -c "[^0-9]" ) -gt 0 ]


après te reste a redécouper la ligne, et remplacer le 3eme champ.

 

En awk c'est nettement plus élégant et plus rapide :

 
Code :
  1. awk -F';' -v OFS=';' '{if ($3~/[^0-9]/) {sub ($3,999999);print $0} else {print $0}}' fichier_csv


Message édité par Nukolau le 15-12-2010 à 17:35:00
n°2042457
aircamus
Posté le 15-12-2010 à 17:47:24  profilanswer
 

Merci à vous deux pour vos réponses. Cependant, quand j'essaye la 2ème commandes proposée, j'ai l'erreur suivante :
 
 
bash-3.00$ awk -F';' -v OFS=';' '{if ($3~/[^0-9]/) {sub ($3,999999);print $0} else {print $0}}' fichier.csv
awk: syntax error near line 1
awk: bailing out near line 1
 
Est-ce que j'ai oublié un truc ?

n°2042582
Nukolau
Posté le 16-12-2010 à 09:35:34  profilanswer
 

Aïe, je n'avais pas fait attention à ca. Sur mon PC awk est lien sur gawk. il semble qu'en awk de base, les expressions régulières soient un peu différentes.
 
Je viens de tester avec oawk et ca fonctionne correctement.
 
Du coup, je ne sais pas te répondre, et j'avoue ne pas avoir trop le temps de chercher...

n°2043235
olivthill
Posté le 20-12-2010 à 10:34:56  profilanswer
 

Peut-être que l'option en awk normale serait FS... au lieu de OFS...
(Personnellement, j'ai toujours utilisé FS..., et je ne suis même pas sûr que cela soit utile, étant donné qu'on a déjà -F...)
Donc essayer :

awk -F';' '{if ($3~/[^0-9]/) {sub ($3,999999);print $0} else {print $0}}' fichier_csv


Mais, peut-être que le problème est ailleurs.
 


Message édité par olivthill le 20-12-2010 à 10:36:39
n°2043246
Nukolau
Posté le 20-12-2010 à 10:59:56  profilanswer
 

Non en fait le OFS c'est le "output field separtor" qui sert à dire a awk de mettre des ; et non des espaces en sortie.

 

EDIT : après test, l'OFS n'est pas obligatoire avec un print $0

 

EDIT 2 : je viens de trouver une solution qui fonctionne sous awk standard, et également sous gawk. C'était bien le -v OFS qui ne fonctionnait pas, mais aussi le if...else et le sub qui ne semble pas exister en awk. Du coup j'ai supprimé les trois et ca fonctionne. On est quand même obligé de remettre le OFS sinon les lignes modifiées ne sont plus séparées par des ; mais des espaces alors que les autres restent bien avec des ;

 
Code :
  1. awk -F';' '{OFS=";"} ; $3~/[^0-9]/ {$3="99999"};{print $0}' fichier_csv

Message cité 1 fois
Message édité par Nukolau le 20-12-2010 à 11:45:39
n°2043346
erulio
Posté le 20-12-2010 à 19:32:24  profilanswer
 

Ça fonctionne ça ? Il me semble que $0 correspond à la ligne entière d'origine, donc sans la modif sur $3. Du coup, t'es obligé de boucler entre $1 et $NF pour avoir la ligne entière mise à jour.

n°2043434
Nukolau
Posté le 21-12-2010 à 09:21:07  profilanswer
 

Ca fonctionne sous awk sur une solaris 10 et en gawk sur une suse 10, je l'ai testé.
J'imagine que ca devrait fonctionner partout du coup.

n°2043928
aircamus
Posté le 23-12-2010 à 09:28:13  profilanswer
 

Nukolau a écrit :

Non en fait le OFS c'est le "output field separtor" qui sert à dire a awk de mettre des ; et non des espaces en sortie.
 
EDIT : après test, l'OFS n'est pas obligatoire avec un print $0
 
EDIT 2 : je viens de trouver une solution qui fonctionne sous awk standard, et également sous gawk. C'était bien le -v OFS qui ne fonctionnait pas, mais aussi le if...else et le sub qui ne semble pas exister en awk. Du coup j'ai supprimé les trois et ca fonctionne. On est quand même obligé de remettre le OFS sinon les lignes modifiées ne sont plus séparées par des ; mais des espaces alors que les autres restent bien avec des ;
 

Code :
  1. awk -F';' '{OFS=";"} ; $3~/[^0-9]/ {$3="99999"};{print $0}' fichier_csv



Merci beaucoup !
 
C'est génial, ça marche parfaitement avec ma version de awk  :bounce:


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Shell/Batch

  [Shell/Batch] Modification de valeurs non numériques dans une colonne

 

Sujets relatifs
[Shell/Batch] Installation de programme en chaîneScript shell scripting bash/Linux
Modification de chaîne de caractères dans un fichier[HELP] Aide sur la création d'un batch moyennement complexe
[MySQL] Ajouter une colonne et les données d'une autre tableprobléme en commande batch
Eclipse Tomcat / modification de servlet non prise en compteProblème de "goto" en batch...
Recherche texte + modification dans un fichier 
Plus de sujets relatifs à : [Shell/Batch] Modification de valeurs non numériques dans une colonne


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR