Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 17/07/2016, à 20:12

Swiss_Knight

awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

Bonsoir bonsoir,

j'ai un gros fichier avec des paramètres en blocs successifs, j'arrive à bien le nettoyer etc, et j'ai extrait des valeurs qui m'intéressaient.
Elles se présentent sous cette forme après un 'paste' bien dégueulasse, big_smile (faut ce qu'il faut!) mais enfin,... ça fonctionne, c'est le principal :

$ cat foo.txt 
01 05 48.3057	15.231	1.2989
01 10 64.9701	21.040	1.2003
01 15 67.9294	25.733	1.2438
01 20 83.1264	30.231	1.1743
02 05 37.2101	15.143	1.2704
02 10 60.3024	22.863	1.1945
02 15 95.2348	28.003	1.1848
02 20 125.873	31.956	1.1904
03 05 46.5343	16.339	1.2586
03 10 123.466	26.151	1.2243
03 15 183.334	33.231	1.2038
03 20 281.140	43.271	1.1939
04 05 48.2704	15.734	1.1990
04 10 145.421	26.795	1.1694
04 15 254.873	37.598	1.1833
04 20 352.355	47.729	1.1592
05 05 37.8022	14.230	1.1611
05 10 123.476	24.480	1.1617
05 15 263.165	37.492	1.1455
05 20 351.715	46.556	1.1350
06 05 55.8306	14.942	1.1703
06 10 145.004	25.638	1.1391
06 15 250.124	35.837	1.1331
06 20 331.153	44.045	1.1216
07 05 67.9651	15.280	1.1436
07 10 146.478	25.234	1.1298
07 15 229.444	33.721	1.1206
07 20 306.139	41.347	1.1132
08 05 61.7691	14.281	1.1279
08 10 135.804	23.901	1.1179
08 15 209.772	31.734	1.1119
08 20 280.850	38.742	1.1079
09 05 54.9907	13.283	1.1189
09 10 124.678	22.546	1.1105
09 15 191.754	29.895	1.1071
09 20 257.529	36.443	1.1045
10 05 48.6915	12.370	1.1126
10 10 114.220	21.273	1.1063
10 15 175.919	28.239	1.1041
10 20 236.672	34.396	1.1025

(j'eusse aimé ne pas devoir sortir le résultat de 'paste' dans un fichier mais je n'arrive pas à conserver ce tableau dans une variable, bon c'est pas très grave ça pour l'instant)

Explications :
En 1ère colonne des coordonnées X, en deuxième colonne des coordonnées Y et dans les colonnes suivantes des valeurs de paramètres quelconques.

J'arrive à extraire que les X semblables ou que les Y semblables avec des boucles for.

Mais j'aimerai surtout pouvoir extraire les trois paramètres dans un tableau chacun donc sous forme de tableau en X\Y (ou Y\X c'est égal) ; par exemple, pour la variable en colonne 3, avoir un résultat de ce style :

48.3057	64.9701	67.9294	83.1264
37.2101	60.3024	95.2348	125.873
46.5343	123.466	183.334	281.13
48.2704	145.421	254.873	352.355
37.8022	123.476	263.165	351.715
55.8306	145.004	250.124	331.153
67.9651	146.478	229.444	306.139
61.7691	135.804	209.772	280.85
54.9907	124.678	191.754	257.529
48.6915	114.29	175.919	236.672

J'ai beau faire des essais dans tous les sens avec ma double boucle for, je n'y arrive pas sad

(et parfois awk me colle toutes les variables : grep "des trucs" | awk -F " " '{ print $1 $2 $3 }' -> tout est collé en sortie !
Y a 10min ça ne me le faisais pas, je n'arrive pas du tout à savoir ce que j'ai touché pour que ça change de comportement.
C'est peut-être une histoire de séparateur espace vs tab je me dis ?!

Ah, et bonus, dans les variables awk, par exemple la $1 on ne peut pas faire de substitution "en direct" (je ne sais pas comment s'appelle cette subtilité) du genre ${1/,/} comme on le ferait avec une variable bash standard, pourquoi ?

Merci beaucoup ! smile

ps : j'ai une solution octave qui tourne au pire, ne vous cassez pas inutilement la tête ! wink

Dernière modification par Swiss_Knight (Le 17/07/2016, à 22:33)


xuniL

Hors ligne

#2 Le 18/07/2016, à 07:03

moko138

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

1) Isoler le cntenu d'une colonne
Compare

dpkg -l | grep linux-image

et

dpkg -l | grep linux-image | tr -s " " | cut -d" " -s -f3 # qui isole la colonne 3.

  - -

2) Ensuite, pour regrouper le retour dans un tableau à 4 colonnes, par contre, je n'ai aucune idée...


%NOINDEX%
Un utilitaire précieux : ncdu
Photo, mini-tutoriel :  À la découverte de dcraw

Hors ligne

#3 Le 18/07/2016, à 07:25

pingouinux

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

Bonjour,
Ce que tu demandes n'est pas très clair (du moins pour moi).
Ceci ?

$ awk -v ORS="" '{if(NR!=1&&$1!=i)print"\n";printf(" %s",$3);i=$1}END{print"\n"}' foo.txt
 48.3057 64.9701 67.9294 83.1264
 37.2101 60.3024 95.2348 125.873
 46.5343 123.466 183.334 281.140
 48.2704 145.421 254.873 352.355
 37.8022 123.476 263.165 351.715
 55.8306 145.004 250.124 331.153
 67.9651 146.478 229.444 306.139
 61.7691 135.804 209.772 280.850
 54.9907 124.678 191.754 257.529
 48.6915 114.220 175.919 236.672
Swiss_Knight #1 a écrit :

(et parfois awk me colle toutes les variables : grep "des trucs" | awk -F " " '{ print $1 $2 $3 }' -> tout est collé en sortie !

awk '/des trucs/{print $1" "$2" "$3}' fichier

Ah, et bonus, dans les variables awk, par exemple la $1 on ne peut pas faire de substitution "en direct" (je ne sais pas comment s'appelle cette subtilité) du genre ${1/,/} comme on le ferait avec une variable bash standard, pourquoi ?

sub(",","",$1)

Dernière modification par pingouinux (Le 18/07/2016, à 07:41)

Hors ligne

#4 Le 18/07/2016, à 08:55

credenhill

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

hello

$ awk '!t[$1] {s[++n]=$1} {t[$1]=t[$1] OFS $3} END {for (a=1; a<=n; )print t[s[a++]]}' fichier
 48.3057 64.9701 67.9294 83.1264
 37.2101 60.3024 95.2348 125.873
 46.5343 123.466 183.334 281.140
 48.2704 145.421 254.873 352.355
 37.8022 123.476 263.165 351.715
 55.8306 145.004 250.124 331.153
 67.9651 146.478 229.444 306.139
 61.7691 135.804 209.772 280.850
 54.9907 124.678 191.754 257.529
 48.6915 114.220 175.919 236.672

edit: plus simple

$ awk '!t[$1] && n++ {print ""} {t[$1]++; printf $3 " "} END {print ""}' fichier

Dernière modification par credenhill (Le 18/07/2016, à 10:28)

Hors ligne

#5 Le 19/07/2016, à 12:46

Swiss_Knight

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

Salut, merci pour vos réponses big_smile
elles fonctionnent toutes très bien, sauf que je me suis mal exprimé, du coup elles ne fonctionnent bien qu'à un tiers.

En fait dans la colonne 1 j'ai les indices i des lignes du tableau et en colonne 2 les indices j des colonnes.
Il faut vraiment voir les deux premières colonnes comme des indices ou des coordonnées d'une matrice. C'est ce que ces valeurs sont !

Chaque colonne supplémentaire correspond à une variable qui prend les valeurs affichées pour les x et y correspondant (dans les colonnes 1 et 2).

Par exemple la première ligne :

01 05 48.3057	15.231	1.2989

Nous dit que pour i=1 et j=5 la variable 1 vaut 48.3057, la variable 2 : 15.231 et la variable 3 : 1.2989.
Et ainsi de suite pour tous les couples (x,y) ou (i,j) indiqués.


Et j'aimerais sortir chaque variable dans une matrice de i ligne et j colonnes.

Petite subtilité ; en fait ici j prend successivement les valeurs 5, 10, 15, 20.
Il ne faudrait pas qu'entre 5 et 10 il y ait les colonnes 6, 7, 8, 9 qui soient vides, etc. (bon ça au pire c'est vraiment pas grave).

Comme expliqué, j'ai une solution qui tourne sous octave donc si vraiment c'est trop compliqué à faire en bash c'est pas grave non plus.
C'est sans doute pas vraiment fait pour ça en fait et il faudrait partir du fichier de base pour extraire les valeurs mieux que je ne l'ai fait avant mais ça j'ai pas le temps de faire ni l'envie.

Dernière modification par Swiss_Knight (Le 19/07/2016, à 12:48)


xuniL

Hors ligne

#6 Le 19/07/2016, à 13:37

Compte anonymisé

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

Bonjour,

quelque chose comme ça ? (pour la 3ième colonne déjà)

#!/bin/bash
fichier=foo.txt
y=$(cut -f 2 -d " " "$fichier"|sort -u)
#première ligne
	printf "x,y\t"
	for j in $y
	do
		printf "$j\t"
	done
	printf "\n"

for i in $(cut -f 1 -d " " "$fichier"|sort -u)
do 
printf "$i\t"
	for j in $y
	do
	printf "$(cat "$fichier"|grep "$i $j "|cut -f 1 -d "	"|cut -f 3 -d " ")\t"
	done
printf "\n"
done

résultat :

$ cat foo.txt 
01 05 48.3057	15.231	1.2989
01 10 64.9701	21.040	1.2003
01 15 67.9294	25.733	1.2438
01 20 83.1264	30.231	1.1743
02 05 37.2101	15.143	1.2704
02 10 60.3024	22.863	1.1945
02 15 95.2348	28.003	1.1848
02 20 125.873	31.956	1.1904
03 05 46.5343	16.339	1.2586
03 10 123.466	26.151	1.2243
03 15 183.334	33.231	1.2038
03 20 281.140	43.271	1.1939
04 05 48.2704	15.734	1.1990
04 10 145.421	26.795	1.1694
04 15 254.873	37.598	1.1833
04 20 352.355	47.729	1.1592
05 05 37.8022	14.230	1.1611
05 10 123.476	24.480	1.1617
05 15 263.165	37.492	1.1455
05 20 351.715	46.556	1.1350
06 05 55.8306	14.942	1.1703
06 10 145.004	25.638	1.1391
06 15 250.124	35.837	1.1331
06 20 331.153	44.045	1.1216
07 05 67.9651	15.280	1.1436
07 10 146.478	25.234	1.1298
07 15 229.444	33.721	1.1206
07 20 306.139	41.347	1.1132
08 05 61.7691	14.281	1.1279
08 10 135.804	23.901	1.1179
08 15 209.772	31.734	1.1119
08 20 280.850	38.742	1.1079
09 05 54.9907	13.283	1.1189
09 10 124.678	22.546	1.1105
09 15 191.754	29.895	1.1071
09 20 257.529	36.443	1.1045
10 05 48.6915	12.370	1.1126
10 10 114.220	21.273	1.1063
10 15 175.919	28.239	1.1041
10 20 236.672	34.396	1.1025
$ bash test.sh 
x,y	05	10	15	20	
01	48.3057	64.9701	67.9294	83.1264	
02	37.2101	60.3024	95.2348	125.873	
03	46.5343	123.466	183.334	281.140	
04	48.2704	145.421	254.873	352.355	
05	37.8022	123.476	263.165	351.715	
06	55.8306	145.004	250.124	331.153	
07	67.9651	146.478	229.444	306.139	
08	61.7691	135.804	209.772	280.850	
09	54.9907	124.678	191.754	257.529	
10	48.6915	114.220	175.919	236.672	

#7 Le 19/07/2016, à 15:32

credenhill

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

$ awk 'BEGIN {print "\t05\t10\t15\t20"} !t[$1] {n++? c=RS: c=""; printf c $1 " "} {t[$1]++; printf $3 " "} END {print ""}' fichier
	05	10	15	20
01 48.3057 64.9701 67.9294 83.1264 
02 37.2101 60.3024 95.2348 125.873 
03 46.5343 123.466 183.334 281.140 
04 48.2704 145.421 254.873 352.355 
05 37.8022 123.476 263.165 351.715 
06 55.8306 145.004 250.124 331.153 
07 67.9651 146.478 229.444 306.139 
08 61.7691 135.804 209.772 280.850 
09 54.9907 124.678 191.754 257.529 
10 48.6915 114.220 175.919 236.672

Hors ligne

#8 Le 19/07/2016, à 16:12

MicP

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

…awk me colle toutes les variables : grep "des trucs" | awk -F " " '{ print $1 $2 $3 }' -> tout est collé en sortie !…

en séparant le nom des variables par des virgules

$ echo -e "premier deuxième troisième\nquatrième cinquième sixième" | awk '{ print $1, $2, $3 }' 
premier deuxième troisième
quatrième cinquième sixième

pas la peine de spécifier l'espace avec -F " " , ce caractère fait déjà partie de la variable la variable $IFS des caractères de séparation de champs par défaut de awk qui sont les caractères espace et tabulation

EDIT : voir mon message suivant

Dernière modification par MicP (Le 19/07/2016, à 16:48)

Hors ligne

#9 Le 19/07/2016, à 16:24

credenhill

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

j'ajouterais que la virgule représente  OFS, par defaut un espace

$ echo -e "premier deuxième troisième\nquatrième cinquième sixième" | awk -v OFS=" + " '{ print $1, $2, $3 }' 
premier + deuxième + troisième
quatrième + cinquième + sixième

Hors ligne

#10 Le 19/07/2016, à 17:02

MicP

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

Effectivement, dans mon précédent message, j'avais parlé de la variable $IFS du bash mais awk ne s'en sert pas :

$ IFSsauv=$IFS; unset IFS; echo -e "premier deuxième troisième\nquatrième cinquième sixième" | awk '{ print $1, $2, $3 }'; IFS="${IFSsauv}"
premier deuxième troisième
quatrième cinquième sixième

Pour info, IFS (Internal Field Separator) est une variable du bash à laquelle est associé un chaîne de caractères contenant les trois caractères suivants : espace, tabulation, saut de ligne

$ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|

=======
awk a ses propres variables pour les caractères de séparation : FS, OFS, RS, ORS

FS	input File Separator	Espace ou tabulation	0x20 ou 0x09
OFS	Output File Separator	Espace ou tabulation	0x20 ou 0x09
RS	input Record Separator	Saut de ligne (LF) 	0x0a
ORS	Output Record Separator	Saut de ligne (LF)	0x0a

Les caractères de séparation des champs par défaut d'awk sont les caractères espace et tabulation
Ces caractères de séparation de champs par défaut sont modifiables avec -F <mon choix de caractère(s) de séparation>

=======
Merci credenhill smile

=======

Swiss_Knight a écrit :

…j'eusse aimé ne pas devoir sortir le résultat de 'paste' dans un fichier mais je n'arrive pas à conserver ce tableau dans une variable…

utilise la commande | entre celle qui te génère le fichier foo.txt (en enlevant le nom du fichier de sortie) et les commandes appliquées au fichier foo.txt

Dernière modification par MicP (Le 20/07/2016, à 08:59)

Hors ligne

#11 Le 20/07/2016, à 08:06

credenhill

Re : awk (ou autre) séparer des variables dans des tableaux (ou fichiers)

IFS en sortie déped comment on résout la variable

$ var=(aa bb cc); IFS="+"; echo "${var[@]}" 
aa bb cc
$ var=(aa bb cc); IFS="+"; echo "${var[*]}" 
aa+bb+cc

Hors ligne