#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, (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
(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 !
ps : j'ai une solution octave qui tourne au pire, ne vous cassez pas inutilement la tête !
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
(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
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
=======
…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