Mise en forme d'un fichier via un shell

Résolu
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention   -  
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention   -
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.
A voir également:

11 réponses

jisisv Messages postés 3645 Date d'inscription   Statut Modérateur Dernière intervention   934
 
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
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
jisisv Messages postés 3645 Date d'inscription   Statut Modérateur Dernière intervention   934
 
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
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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 ?
0
jisisv Messages postés 3645 Date d'inscription   Statut Modérateur Dernière intervention   934
 
printf("%s\t(%s)\t%04d>%04d\n", key, NAME[key], MIN[key], MAX[key] );
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
$ 
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
$ 
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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 ...
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
$ 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
$ 
$ 
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
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
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
dubcek Messages postés 18789 Date d'inscription   Statut Contributeur Dernière intervention   5 637
 
$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
$ 
0
lucie31000 Messages postés 9 Date d'inscription   Statut Membre Dernière intervention  
 
Super !


Encore merci.

PS : cloturer le post
0