Mise en forme d'un fichier via un shell [Résolu/Fermé]

Signaler
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012
-
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012
-
Bonjour à toutes et à tous,

Est-it possible de comparer les valeurs contenues dans un fichier texte avec des commandes shell ?

Voici le contenu de mon fichier :

AAA 100 0:0:0:0:0 Marc Dupont
BBB 200 0:0:0:0:0 Jean Durand
CCC 300 0:0:0:0:0 Alain Duplat
AAA 150 0:0:0:0:0 Marc Dupont
BBB 250 0:0:0:0:0 Jean Durand
CCC 350 0:0:0:0:0 Alain Duplat

et le resultat souhaité :

AAA Marc Dupont 100>150
BBB Jean Durand 200>250
CCC Alain Duplat 300>350

sachant que les espaces sont des tabulations, sauf entre les noms/prénoms :(

Merci beaucoup pour vos conseils.

11 réponses

Messages postés
3645
Date d'inscription
dimanche 18 mars 2001
Statut
Modérateur
Dernière intervention
15 janvier 2017
942
Tu peux utiliser awk qui est un utilitaire standard UNIX:<code><gras>johand@osiris: ~/src/CCM/awk $ cat limits.dat
AAA 100 0:0:0:0:0 Marc Dupont
BBB 200 0:0:0:0:0 Jean Durand
CCC 300 0:0:0:0:0 Alain Duplat
AAA 150 0:0:0:0:0 Marc Dupont
BBB 250 0:0:0:0:0 Jean Durand
CCC 350 0:0:0:0:0 Alain Duplat
johand@osiris: ~/src/CCM/awk $ cat limits.sh
#!/bin/sh
awk -F "\t" '{NAME[$1] = $4;
if ( MIN[$1] > $2 || MIN[$1] == 0)
MIN[$1]= $2 ;
if ( MAX[$1] < $2 )
MAX[$1] =$2;}
END {for (key in NAME )
{ printf("%s\t%s\t%04d>%04d\n", key, NAME[key], MIN[key], MAX[key] ); }
}'| sort

johand@osiris: ~/src/CCM/awk $ ./limits.sh < limits.dat
AAA Marc Dupont 0100>0150
BBB Jean Durand 0200>0250
CCC Alain Duplat 0300>0350
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

Merci de votre réponse rapide.

Mon but est de faire les différentes mises en forme puis d'imprimer le résultat dans la console. J'ai donc intégré votre code à mon shell (car j'ai d'autres mises en forme faites avant) et j'ai donc ceci :

awk -F "\t" '{ ..... }'| sort mon_fichier
more mon_fichier


Mais le promp ne me rends pas la main et n'imprime pas les valeurs attendues.

Est-ce que ça ne vient pas de la commande printf utlisée avec le awk ?

Merci bcp.
LD
Messages postés
3645
Date d'inscription
dimanche 18 mars 2001
Statut
Modérateur
Dernière intervention
15 janvier 2017
942
Dans ton script tu places le code
cat fichier_d_origine | awk -F "\t" '{NAME[$1] = $4;
if ( MIN[$1] > $2 || MIN[$1] == 0)
MIN[$1]= $2 ;
if ( MAX[$1] < $2 )
MAX[$1] =$2;}
END {for (key in NAME )
{ printf("%s\t%s\t%04d>%04d\n", key, NAME[key], MIN[key], MAX[key] ); }
}'  | sort > fichier_cible


Tu adaptera évidemment selon tes besoins
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

C'est passé !

Deux remarques :

- Si la valeur min est 0 et que la valeur max est 100, la fonction indique 100>100 C'est bizarre ;)

- Pour la lisibilité, je souhaite ajouter des parenthèses et obtenir AAA (Marc Dupont) 0100>0150
Mais j'ai une erreur de synthaxe sur la ligne :
{ printf("%s\t%s\t%04d>%04d\n", key, %04d(%04dNAME[key]%04d=%04d, MIN[key], MAX[key] ); }


%04d n'est pas utilisable pour insérer des parenthèses ?
Messages postés
3645
Date d'inscription
dimanche 18 mars 2001
Statut
Modérateur
Dernière intervention
15 janvier 2017
942
printf("%s\t(%s)\t%04d>%04d\n", key, NAME[key], MIN[key], MAX[key] );
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

Merci pour les parenthèses !

Je suis vraiment coincé quand mes valeurs MIN sont à 0, même en mettant
if ( MIN[$1] > $2)
, je n'obtiens pas 000>100 par exemple.

LD
Messages postés
18242
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
13 juin 2021
5 308
hello
$ awk -F'\t' '{t[$NF] ? c=">": c=""; t[$NF]=t[$NF] c $2; t2[$NF]=$1} END{for(n in t){print t2[n], n, t[n]}}' fichier
CCC Alain Duplat 300>350
BBB Jean Durand 200>250
AAA Marc Dupont 100>150
$ 
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

bonsoir

merci pour votre contribution, avez vous testé le script avec comme exemple des valeurs min à 0 ? Qui donnerai :

CCC Alain Duplat 000>350
BBB Jean Durand 000>250
AAA Marc Dupont 000>150

Je suis en déplacement et je ne peux tester le code ;)

Merci
Messages postés
18242
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
13 juin 2021
5 308
que faut-il tester ?
$ cat fichier
AAA	000	0:0:0:0:0	Marc Dupont
BBB	000	0:0:0:0:0	Jean Durand
CCC	000	0:0:0:0:0	Alain Duplat
AAA	150	0:0:0:0:0	Marc Dupont
BBB	250	0:0:0:0:0	Jean Durand
CCC	350	0:0:0:0:0	Alain Duplat
$ awk -F'\t' '{t[$NF] ? c=">": c=""; t[$NF]=t[$NF] c $2; t2[$NF]=$1} END{for(n in t){print t2[n], n, t[n]}}' fichier
CCC Alain Duplat 000>350
BBB Jean Durand 000>250
AAA Marc Dupont 000>150
$ 
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

Oui c'était mon exemple ! merci de l'avoir testé, il me tarde de le valider sur ma machine ..

Pour obtenir :
CCC (Alain Duplat) 000>350

C'est comme ça qu'il faut placer les parenthèses dans le code ?
awk -F'%s\t(%s)\t ...
Messages postés
18242
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
13 juin 2021
5 308
$ awk -F'\t' '{t[$NF] ? c=">": c=""; t[$NF]=t[$NF] c $2; t2[$NF]=$1} END{for(n in t){print t2[n], "(" n ")", t[n]}}' a1
CCC (Alain Duplat) 000>350
BBB (Jean Durand) 000>250
AAA (Marc Dupont) 000>150
$ 
$ 
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

Bonjour,

Je suis trés satisfait du résultat ! Merci dubcek et jisisv

Je me suis apperçu que quand les données n'étaient pas classées dans le même ordre, par exemple :

AAA 150 0:0:0:0:0 Marc Dupont
BBB 250 0:0:0:0:0 Jean Durand
CCC 350 0:0:0:0:0 Alain Duplat
AAA 000 0:0:0:0:0 Marc Dupont
BBB 000 0:0:0:0:0 Jean Durand
CCC 000 0:0:0:0:0 Alain Duplat


J'obtenanait :

CCC Alain Duplat 350>000
BBB Jean Durand 250>000
AAA Marc Dupont 150>000


Confirmez-moi SVP dubcek, que dans votre script, il n'y a pas d'opération de comparaison de valeur (l'une suppérieure à l'autre) mais plutôt la première vue par rapport à la suivante (ayant le même nom); ce qui expliquerait ce résultat.

LD
Messages postés
18242
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
13 juin 2021
5 308
non, il n'y a pas de comparaison. les valeurs sont concaténées pour un même nom.
effectivment l'ordre change, est ce que c'est un problème ?
c'est dû à t[$NF]=t[$NF] qui utilise le nom comme index et pas un index numérique
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

Ca passe, dans la mesure ou je trie les nombres pour les présenter : d'abord valeur min puis valeur max.
Du coup la comparaison de votre script fonctionne bien !

Comment faire la comparaison sur la première colonne ? L'index serait "AAA" par exemple ?
J'ai bien essayé
awk -F'\t' '{t[$0] ...
mais le résultat est NOK

Merci,
LD
Messages postés
18242
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
13 juin 2021
5 308
$0 c'est la ligne entière, $1 est le premier champ
$ awk -F'\t' '{t[$1] ? c=">": c=""; t[$1]=t[$1] c $2; t2[$1]=$NF} END{for(n in t){print n, "(" t2[n] ")", t[n]}}' a1
AAA (Marc Dupont) 000>150
CCC (Alain Duplat) 000>350
BBB (Jean Durand) 000>250
$ 
Messages postés
9
Date d'inscription
samedi 15 septembre 2012
Statut
Membre
Dernière intervention
23 septembre 2012

Super !


Encore merci.

PS : cloturer le post