Formater un fichier avec Sed,Awk,Cut,Sort ..

Résolu/Fermé
Signaler
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
-
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
-
Bonjour,

Dans un fichier j'ai des lignes comme ci-dessous :

50 | 01/02/2010 00:00:00 CET
75 | 01/03/2010 00:00:00 CET
62 | 01/04/2010 00:00:00 CEST
48 | 01/05/2010 00:00:00 CEST


et je souhaiterais formater ces lignes pour les avoir sous la forme :

50 | 02/2010
75 | 03/2010
62 | 04/2010
48 | 05/2010


Avez vous une idée comme je dois procéder?

Merci



11 réponses

Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
Salut,

$ cat plop 
50 | 01/02/2010 00:00:00 CET
75 | 01/03/2010 00:00:00 CET
62 | 01/04/2010 00:00:00 CEST
48 | 01/05/2010 00:00:00 CEST

$ awk 'split($3,x,"/") { print $1,$2,x[2]"/"x[3] }' plop 
50 | 02/2010
75 | 03/2010
62 | 04/2010
48 | 05/2010

$

;-))
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
Ou avec "sed" :

$ sed 's#\(.*\)../\(../....\).*#\1\2#' plop 
50 | 02/2010
75 | 03/2010
62 | 04/2010
48 | 05/2010

$

;-))
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
Salut zipe31,

Houla!! avant d'utiliser tes commandes, il me faut comprendre tes lignes car cela devient un peu complexe pour moi.

En tout cas merci.
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
Pour "awk", rien de bien sorcier.

Extrait :
split(chaine-de-caractères,tableau,séparateur) scinde la chaîne chaine-de-caractères dans un tableau, le séparateur de champ est le troisième argument

split($3,x,"/")
Donc, avec le séparateur de champs par défaut (espace) en entrée, on prend le 3ème champ ($3) qu'on découpe dans un tableau "x" avec pour le tableau un séparateur de champs défini à "/" (slash). Reste plus qu'à extraire les champs qui conviennent (x[2] et x[3]).

Pour "sed" voir dans le FAQ : Les sous-expressions et références arrières ;-))

En gros pour l'expression "\(.*\)../\(../....\).*":

\(.*\)
1ère sous expression qui correspond à "50 | "


../
2 caractères quelconques suivis d'un slash, ce qui correspond à "01/"


\(../....\)
2nde sous expression qui correspond à 2caractères suivis d'un slash puis de 4 caractères, ce qui donne "02/2010"


.*
Le reste de la ligne.

Et au final on affiche que les sous expressions qui conviennent, à savoir la "\1" et la "\2"
0
Messages postés
18410
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
18 janvier 2022
5 535
hello
et en shell
$ IFS=" |/"; while read a b c d e ; do echo $a $c"/"$d ; done < fichier
50 02/2010
75 03/2010
62 04/2010
48 05/2010
$ 
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
Merci Zipe31 pour tes explications qui ne sont pas de trop.

Merci dubcek . En effet ta ligne de commande et assez simple et c'est vraie que je ne penses jamais a while mais cela ne corrspond pas a ce que je souhate puisque je dois garder le | entre le rpemier champ et le second comme ci-dessous :

50 | 02/2010


Merci a vous deux
0
Messages postés
18410
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
18 janvier 2022
5 535
effectivement
$ IFS=" |/"; while read a b c d e ; do echo $a "|" $c"/"$d ; done < a1
50 | 02/2010
75 | 03/2010
62 | 04/2010
48 | 05/2010
$ 
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
Merci dubcek. J'ai un autre fichier avec le contenu suivant :

163567 | 461 | 01/03/2010 00:00:00 CET
1454842 | 473 | 01/04/2010 00:00:00 CEST
1165841 | 459 | 01/05/2010 00:00:00 CEST


en suivant ton exemple j'ai fait :

IFS=" |/"; while read a b c d e ; do echo $a "|" $b "|" $d"/" $e ; done < test.txt

mais cela ne fonctionne pas donc j'ai pas du comprendre ta ligne de commande.
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
Salut,

Si tu rajoutes des champs, il faut aussi rajouter des variables ;-(

IFS=" /";while read a b c d e f g h;do echo $a $b $f"/"$g;done <plop
163567 | 03/2010
1454842 | 04/2010
1165841 | 05/2010

$

J'ai supprimé le "|" comme séparateur de champs et je l'ai rajouté dans les variables ($b)
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
Oups, un poil en retard ;-(
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
C'est bon j'ai compris.

IFS=" |/"; while read a b c d e f g; do echo $a "|" $b "|" $d"/"$e ; done < test.txt

Merci
0
Messages postés
18410
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
18 janvier 2022
5 535
chaque variable prend 1 champ et la dernière prend le reste de la lgne
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
Oups j'ai été un peu vite en faites cela ne fonctionne pas car a la fin du fichier j'ai cela en gras et je ne sais pas pourquoi :

IFS=" |"; while read a b c d e f g; do echo $a "|" $b "|" $d"/"$e ; done < test.txt

1255 | 457 | 00:00:00/CET
1036 | 422 | 00:00:00/CET
| | /
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
IFS=" |"
Parce qu'il manque le "/" comme séparateur ;-(
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
Non même avec le séparateur / que j'ai oublié quand j'ai fait mon copier/coller.

zipe31 toi qui semble incollable sur SED pourrais tu m'aider pour formater le fichier suivant car je peine depuis deux heures a essayer de faire un truc propre :

163567 | 461 | 01/03/2010 00:00:00 CET
1454842 | 473 | 01/04/2010 00:00:00 CEST
1165841 | 459 | 01/05/2010 00:00:00 CEST


en

163567;461;03/2010
1454842;473;04/2010
116584;459;05/2010


Merci beaucoup
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
sed 's#\(.*\)../\(../....\).*#\1\2#;s# | #;#g'
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
IFS=" /";while read a b c d e f g h;do echo $a\;$c\;$f"/"$g;done <fich
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
awk 'BEGIN{ FS="[ |/]";OFS=";" }{ print $1,$4,$8"/"$9 }'
0
He bin j'ai le choix. Merci énormément zipe31 pour ton aide très précieuse pour les personnes comme moi qui se frotte a l'admin système.

Par contre j'ai l'impression que AWK avec la fonction split ne fonctionne pas sur le serveur ou je lance ce script. Faut dire que c'est une vieille machine sous Sarge je crois donc il se peux que la version de Awk... Je dois vérifier cela.

Merci également dubcek.

Je teste tous cela et vient vous dire ce qu'il en est.

Bonne soirée à vous deux.
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
Bonjour zipe31, la ligne de commande :

sed 's#\(.*\)../\(../....\).*#\1\2#;s# | #;#g'  


semble ne pas fonctionner en ce qui concerne les remplacement du | par le ;

Mon fichier pif.txt contient :

1443|473|01/03/2011 00:00:00 CET
1275|472|01/04/2011 00:00:00 CEST

si je saisie en console

sed 's#\(.*\)../\(../....\).*#\1\2#;s# | #;#g' pif.txt 


voila ce que j'ai

1443|473|03/2011
1275|472|04/2011

Merci
L'accès au savoir est la première liberté que chaque homme devrait avoir.
0
Messages postés
36324
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 587
Salut,

Ben forcément, dans ton exemple précédent il y avait des espaces autour du pipe, alors que maintenant il n'y en a pas ;-(

sed 's#\(.*\)../\(../....\).*#\1\2#;s#|#;#g'

Devrait aller mieux ;-))
0
Messages postés
631
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
6 janvier 2022
19
En faites il n'y a pas d'espaces depuis le départ dans mon exemple mais c'est lors de mon copier/coller .Désolé et merci

C'est good!
0