Traitement fichier avec Sed, Awk ou autres
Résolu
pcsystemd
Messages postés
734
Statut
Membre
-
pcsystemd Messages postés 734 Statut Membre -
pcsystemd Messages postés 734 Statut Membre -
Bonjour,
J'ai un fichier de données qui contient des milliers de lignes comme suite :
Celui ci contient 21 champs séparés par des pipes |
J'aurais souhaité pouvoir remplacer les virgules des champs 20 et 21 (les derniers) par des points comme suite :
J'ai besoin d' aide.
Merci
--
L'accès au savoir est la première liberté que chaque homme devrait avoir.
J'ai un fichier de données qui contient des milliers de lignes comme suite :
1001|20015232851|||25 bld totl||75000|Paris||6|JOEAU|2206000|24/05/2013|25/06/2015||2001|2001|17592|C|48,860274|2,345089
1001|20015246491|||41 rue court||75000|Paris||6|CAENS|289000|28/02/2014|30/07/2015||2001|2001|16141|C|48,88000|2,32417
Celui ci contient 21 champs séparés par des pipes |
J'aurais souhaité pouvoir remplacer les virgules des champs 20 et 21 (les derniers) par des points comme suite :
1001|20015232851|||25 bld totl||75000|Paris||6|JOEAU|2206000|24/05/2013|25/06/2015||2001|2001|17592|C|48.860274|2.345089
1001|20015246491|||41 rue court||75000|Paris||6|CAENS|289000|28/02/2014|30/07/2015||2001|2001|16141|C|48.88000|2.32417
J'ai besoin d' aide.
Merci
--
L'accès au savoir est la première liberté que chaque homme devrait avoir.
4 réponses
-
hello
$ awk 'BEGIN {FS=OFS="|"} {sub(",", ".", $20); sub(",", ".", $21); print}' fichier
1001|20015232851|||25 bld totl||75000|Paris||6|JOEAU|2206000|24/05/2013|25/06/2015||2001|2001|17592|C|48.860274|2.345089
1001|20015246491|||41 rue court||75000|Paris||6|CAENS|289000|28/02/2014|30/07/2015||2001|2001|16141|C|48.88000|2.32417 -
Bon finalement j'ai trouvé avec Sed.
sed -e 's/|\([0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9]\) [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/|\1/g' -e 's/,/./g' fichier1 > fichier2
Merci
-
Ta solution ne limite pas la substitution aux colonnes 20 et 21. Avec awk :
cat toto.txt | awk 'BEGIN {FS="|"} ; {printf("%s",$1); for(i=2;i<20;i++) printf("|%s",$(i)); for(i=20;i<22;i++){ s=$(i); gsub(/,/, ".", s); printf("|%s",s);} print "";}'
Ou de manière plus lisible si tu passes par un fichier script.awk :
BEGIN { FS="|" } { printf("%s", $1); for (i = 2; i < 20; i++) { printf("|%s", $(i)); } for (i = 20; i < 22; i++) { s = $(i); gsub(/,/, ".", s); printf("|%s", s); } print ""; }
Puis :
cat toto.txt | awk -f script.awk
Exemple :
(mando@velvet) (~) $ cat toto.txt | awk 'BEGIN {FS="|"} ; {printf("%s",$1); for(i=2;i<20;i++) printf("|%s",$(i)); for(i=20;i<22;i++){ s=$(i); gsub(/,/, ".", s); printf("|%s",s);} print "";}'
1001|20015232851|||25 bld totl||75000|Paris||6|JOEAU|2206000|24/05/2013|25/06/2015||2001|2001|17592|C|48.860274|2.345089
1001|20015246491|||41 rue court||75000|Paris||6|CAENS|289000|28/02/2014|30/07/2015||2001|2001|16141|C|48.88000|2.32417
Bonne chance-
-
Merci pour cette remarque très pertinente, car aux index près (
$20
et$21
au lieu de$21
et$22
), c'est effectivement beaucoup plus simple !
awk 'BEGIN {FS = OFS = "|"}; { gsub(/,/, ".", $20); gsub(/,/, ".", $21); print }'
Je ne savais pas qu'altérer$20
et$21
permettait d'altérer implicitement$0
(implicitement passé en argument du dernier print). L'idée de changerOFS
pour éviter de le ré-indiquer dans leprint
est également bien vue.
Edit : j'ai vu la réponse de dubcek après coup.
-
-