[BASH / AWK] Modification complexe de champ
Résolu/Fermé
A voir également:
- [BASH / AWK] Modification complexe de champ
- Suivi de modification word - Guide
- Logiciel modification pdf gratuit - Guide
- Modification dns - Guide
- Modification d'écriture - Guide
8 réponses
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
2 févr. 2010 à 10:57
2 févr. 2010 à 10:57
Salut,
je souhaite eviter perl car il n'est pas installé sur la machine de prod que j'utilise.
Ta machine de prod as un os GNU/Linux ou Unix?
Si oui alors perl est installé ;-)
je souhaite eviter perl car il n'est pas installé sur la machine de prod que j'utilise.
Ta machine de prod as un os GNU/Linux ou Unix?
Si oui alors perl est installé ;-)
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
2 févr. 2010 à 11:10
2 févr. 2010 à 11:10
Re,
Je n'ai pas le temps pour me pencher sur ton problème puisque je suis au boulot.
Si entre temps tu n'auras pas une réponse (je pense à dubcek ou jipicy ;-) mais ça peut être n'importe qui d'ailleurs ;-) ) alors je vais regarder ce soir.
Je n'ai pas le temps pour me pencher sur ton problème puisque je suis au boulot.
Si entre temps tu n'auras pas une réponse (je pense à dubcek ou jipicy ;-) mais ça peut être n'importe qui d'ailleurs ;-) ) alors je vais regarder ce soir.
dubcek
Messages postés
18755
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
14 novembre 2024
5 621
2 févr. 2010 à 14:33
2 févr. 2010 à 14:33
hello
- le fichier a1 contient les lignes d'exemple
- avec split("8,14,22,29,36,44",x,",") on initialise un tableau x contenant les No de champs qu'on veut traiter
- est ce une adresse valide ? 48238784 == 0.12.1.46
- le fichier a1 contient les lignes d'exemple
- avec split("8,14,22,29,36,44",x,",") on initialise un tableau x contenant les No de champs qu'on veut traiter
- est ce une adresse valide ? 48238784 == 0.12.1.46
$ echo -1139627840 320733888 | awk '{for(i=1;i<=NF;i++){ip=sprintf("%x", $i);printf("%d.%d.%d.%d ", "0x" substr(ip,7,2), "0x" substr(ip,5,2), "0x" substr(ip,3,2), "0x" substr(ip,1,2))};print ""}' 192.168.18.188 192.2.30.19 $ $ awk -F, '{print $8, $14, $22, $29, $36, $44}' a1 -516943680 0 0 48238784 0 0 -516943680 0 0 0 0 0 -887353152 -887353152 0 320733888 320733888 0 $ $ awk -F, 'BEGIN{split("8,14,22,29,36,44",x,",")};{for(i in x) {ip=sprintf("%x", $(x[i]));printf("%d.%d.%d.%d ", "0x" substr(ip,7,2), "0x" substr(ip,5,2), "0x" substr(ip,3,2), "0x" substr(ip,1,2))};print ""}' < a1 192.16.48.225 0.0.0.0 0.0.0.0 0.12.1.46 0.0.0.0 0.0.0.0 192.16.48.225 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 0.0.0.0 192.16.28.203 192.16.28.203 0.0.0.0 192.2.30.19 192.2.30.19 0.0.0.0 $
Bonjour Dubcek,
Merci pour ta réponse et désolé pour le retour tardif. Je pense comprendre le principe de ce que tu proposes, néanmoins chez moi ça retourne uniquement des 0.0.0.0.
Après un peu de tests :
netprd04@netprdadm02#echo -1139627840 | awk '{ip=sprintf("%x", $1); print(ip); print(substr(ip,15,2)); printf("%d ", "0x" substr(ip,15,2)); print("")}'
retourne :
ffffffffbc12a8c0
c0
0
il y a un problème avec la conversion hexa vers decimal, mais je n'arrive pas à voir d'où ça vient...
Je ne comprends pas non plus pourquoi chez toi les substr sur les digits 7, 5, 3, 1 fonctionnent à la fois fois sur les nombres positifs (8 digits en hexa chez moi) et négatifs (16 digits en hexa chez moi).
ma version de awk est GNU AWK 3.1.5, peut-être est-ce que ça vient de là ?
Merci pour ton intérêt pour mon problème en tout cas !
Nicooo.
Merci pour ta réponse et désolé pour le retour tardif. Je pense comprendre le principe de ce que tu proposes, néanmoins chez moi ça retourne uniquement des 0.0.0.0.
Après un peu de tests :
netprd04@netprdadm02#echo -1139627840 | awk '{ip=sprintf("%x", $1); print(ip); print(substr(ip,15,2)); printf("%d ", "0x" substr(ip,15,2)); print("")}'
retourne :
ffffffffbc12a8c0
c0
0
il y a un problème avec la conversion hexa vers decimal, mais je n'arrive pas à voir d'où ça vient...
Je ne comprends pas non plus pourquoi chez toi les substr sur les digits 7, 5, 3, 1 fonctionnent à la fois fois sur les nombres positifs (8 digits en hexa chez moi) et négatifs (16 digits en hexa chez moi).
ma version de awk est GNU AWK 3.1.5, peut-être est-ce que ça vient de là ?
Merci pour ton intérêt pour mon problème en tout cas !
Nicooo.
dubcek
Messages postés
18755
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
14 novembre 2024
5 621
3 févr. 2010 à 09:49
3 févr. 2010 à 09:49
j'utilise le awk traditionnel, effectivement gawk agit différement.
essaye gawk avec --posix
essaye avec mawk, le awk traditionnel
essaye gawk avec --posix
essaye avec mawk, le awk traditionnel
0 $ echo -1139627840 | gawk --posix '{ip=sprintf("%x", $1); print(ip); print(substr(ip,15,2)); printf("%d ", "0x" substr(ip,15,2)); print("")}' ffffffffbc12a8c0 c0 192
hello,
j'ai essayé avec :
- gawk --posix ou gawk -W posix : je tombe sur le même résultat
- mawk : inconnu, je ne le trouve pas en faisant find / -name *awk*
A priori tous les awk, gawk, pgawk, igawk de /bin ou /usr/bin sont de la même version (3.1.5).
Si j'utilise l'option que j'avais trouvé sur le net (--non-decimal-data), ça tourne à peu près :
netprd04@netprdadm02#echo -1139627840 320733888 | awk --non-decimal-data '{for(i=1;i<=NF;i++){ip=sprintf("%x", $i);printf("%d.%d.%d.%d ", "0x" substr(ip,7,2), "0x" substr(ip,5,2), "0x" substr(ip,3,2), "0x" substr(ip,1,2))};print ""}'
255.255.255.255 192.2.30.19
Par contre comme les conversions de nombres négatifs sont sur 16 chiffres chez moi, je vais être obligé d'utilsier une structure conditionnelle je pense, à moisn q'uil existe un moyen de compter les digits à partir de la droite ?
Merci.
j'ai essayé avec :
- gawk --posix ou gawk -W posix : je tombe sur le même résultat
- mawk : inconnu, je ne le trouve pas en faisant find / -name *awk*
A priori tous les awk, gawk, pgawk, igawk de /bin ou /usr/bin sont de la même version (3.1.5).
Si j'utilise l'option que j'avais trouvé sur le net (--non-decimal-data), ça tourne à peu près :
netprd04@netprdadm02#echo -1139627840 320733888 | awk --non-decimal-data '{for(i=1;i<=NF;i++){ip=sprintf("%x", $i);printf("%d.%d.%d.%d ", "0x" substr(ip,7,2), "0x" substr(ip,5,2), "0x" substr(ip,3,2), "0x" substr(ip,1,2))};print ""}'
255.255.255.255 192.2.30.19
Par contre comme les conversions de nombres négatifs sont sur 16 chiffres chez moi, je vais être obligé d'utilsier une structure conditionnelle je pense, à moisn q'uil existe un moyen de compter les digits à partir de la droite ?
Merci.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
lami20j
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 569
3 févr. 2010 à 10:52
3 févr. 2010 à 10:52
Re,
Une piste?!!!
Pourquoi pas utiliser l'opérateur de décalage (il me semble qu'il existe aussi en awk)
https://www.commentcamarche.net/faq/10440-conversion-d-une-adresse-ip-en-entier-32-bits
https://www.commentcamarche.net/faq/10443-conversion-d-un-nombre-entier-32-bits-en-ip
Une piste?!!!
Pourquoi pas utiliser l'opérateur de décalage (il me semble qu'il existe aussi en awk)
https://www.commentcamarche.net/faq/10440-conversion-d-une-adresse-ip-en-entier-32-bits
https://www.commentcamarche.net/faq/10443-conversion-d-un-nombre-entier-32-bits-en-ip
dubcek
Messages postés
18755
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
14 novembre 2024
5 621
3 févr. 2010 à 12:34
3 févr. 2010 à 12:34
on teste si la valeur est < 0, et on elimine ffffffff : $i < 0 ? n=9:n=0; ip=substr(sprintf("%x",$i),n)
avec gawk --posix, il comprend printf("%d ", "0x" substr(ip,7,2) pour imprimer en décimal un hexa, sinon il faudrait faire : printf("%d ", strtonum("0x" substr(ip,7,2)) ...
$ echo -1139627840 320733888 | gawk --posix '{for(i=1;i<=NF;i++){$i < 0 ? n=9:n=0; ip=substr(sprintf("%x",$i),n);printf("%d.%d.%d.%d ", "0x" substr(ip,7,2), "0x" substr(ip,5,2), "0x" substr(ip,3,2), "0x" substr(ip,1,2))};print ""}' 192.168.18.188 192.2.30.19
avec gawk --posix, il comprend printf("%d ", "0x" substr(ip,7,2) pour imprimer en décimal un hexa, sinon il faudrait faire : printf("%d ", strtonum("0x" substr(ip,7,2)) ...
$ echo 320733888 | gawk '{ip=sprintf("%x",$1);printf("%d", "0x" substr(ip,7,2));print ""}' 0 $ echo 320733888 | gawk --posix '{ip=sprintf("%x",$1);printf("%d", "0x" substr(ip,7,2));print ""}' 192 $ $ echo 320733888 | gawk '{ip=sprintf("%x",$1);printf("%d", strtonum("0x" substr(ip,7,2)));print ""}' 192 $
dubcek
Messages postés
18755
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
14 novembre 2024
5 621
3 févr. 2010 à 15:04
3 févr. 2010 à 15:04
ou aussi
$ echo -1139627840 320733888|gawk '{for(i=1;i<=NF;i++){ip=sprintf("%x",and($i,0x00000000ffffffff));for(n=7;n>0;n-=2){printf("%d",strtonum("0x" substr(ip,n,2)));if(n>1)printf(".")};print ""}}' 192.168.18.188 192.2.30.19 $
Alright !
Bon alors voilà ce que j'ai fait finalement :
- testfile contient les lignes d'exemple ci-dessus.
- ligne de commande : cat testfile | awk --non-decimal-data -F, 'BEGIN{date[1]=5;date[2]=48;date[3]=49;ipaddr[1]=8;ipaddr[2]=14;ipaddr[3]=22;ipaddr[4]=29;ipaddr[5]=36;ipaddr[6]=44};{for(i in date){$(date[i])=strftime("%F %X", $(date[i]))};for(j in ipaddr){$(ipaddr[j]) < 0 ? n=9:n=0;ip=substr(sprintf("%8x",$(ipaddr[j])),n);$(ipaddr[j])=sprintf("%d.%d.%d.%d ", "0x"substr(ip,7,2), "0x"substr(ip,5,2), "0x"substr(ip,3,2), "0x"substr(ip,1,2))};print $0}'
- résultat :
1 2 42698 44111624 2008-05-27 14:03:47 2 0 192.16.48.225 "95011" "95011" 0 17 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 44111628 2 0 192.16.224.0 "54790" "98500004" "" 0 0 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 1970-01-01 01:00:00 2008-05-27 14:03:48 "54790" "0aaaa261-d245-4264-b09d-6ac17129a5e4" "PBX_FR-PBX" "_Globals_DNs" "_Globals_DNs" "PBX_FR-PBX" 0 "SEP001E4AAAAAA7" "IPMA-RP" 12 0 1 1 18 18 0 "Cluster1" 1 "" "" 0 "" 3 1 0 0 0 0 ""
1 2 42699 44111631 2008-05-27 14:04:06 2 0 192.16.48.225 "95011" "95011" 0 1 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 44111632 0 0 0.0.0.0 "54576" "54576" "" 0 0 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 1970-01-01 01:00:00 2008-05-27 14:04:07 "54576" "558aaaa5-225c-4f4c-a4df-9181e09c2f1f" "" "_Globals_DNs" "" "" 0 "SEP001E4AAAAAA7" "" 13 0 0 0 0 0 0 "Cluster1" 0 "" "" 0 "" 3 0 0 0 0 0 ""
1 2 42696 44111613 2008-05-27 14:01:14 2 0 192.16.28.203 "49240" "49240" 0 0 4 192.16.28.203 18454 4 20 0 0 0 0 0.0.0.0 0 "0" "0" 44111614 2 30 192.2.30.19 "00142148396" "00142148396" "" 0 16 4 192.2.30.19 18380 4 20 0 0 0 0 0.0.0.0 0 "0" "0" 2008-05-27 14:01:17 2008-05-27 14:04:28 "00142148396" "0abaaaa7-2990-48df-81d7-e9d015186857" "PBX_PSTN-FR-Granite" "_Globals_DNs" "PBX_PSTN-FR-Granite" "PBX_PSTN-FR" 191 "SEP001E7ACAAAA1" "S0/SU0/DS1-1@DEF-C50" 0 12 0 0 0 0 0 "Cluster1" 0 "" "" 0 "" 3 1 0 0 64 64 ""
Donc mes dates sont devenues lisibles, et les adresses ip aussi. :o)
Pour info :
- la fonction strtonum() marche bien aussi, cependant il aurait fallu l'écrire 4 fois pour envelopper les "0x" substr(ip,x,y), donc j'ai préféré réutiliser l'option --non-decimal-data qui marche chez moi et donne le même résultat.
- l'adresse ip en 0.12.1.46 venait du fait que la conversion en hexa du décimal 320733888 tient sur 7 digits, ce qui est a priori résolu en forçant le format de l'affichage avec sprintf("%8x",$(ipaddr[j])).
Un grand merci à tous les deux pour votre aide précieuse et pour le temps que vous avez bien voulu consacrer à mon problème !!!
Félicitations aussi pour votre maitrise de awk ;)
Nicooo
Bon alors voilà ce que j'ai fait finalement :
- testfile contient les lignes d'exemple ci-dessus.
- ligne de commande : cat testfile | awk --non-decimal-data -F, 'BEGIN{date[1]=5;date[2]=48;date[3]=49;ipaddr[1]=8;ipaddr[2]=14;ipaddr[3]=22;ipaddr[4]=29;ipaddr[5]=36;ipaddr[6]=44};{for(i in date){$(date[i])=strftime("%F %X", $(date[i]))};for(j in ipaddr){$(ipaddr[j]) < 0 ? n=9:n=0;ip=substr(sprintf("%8x",$(ipaddr[j])),n);$(ipaddr[j])=sprintf("%d.%d.%d.%d ", "0x"substr(ip,7,2), "0x"substr(ip,5,2), "0x"substr(ip,3,2), "0x"substr(ip,1,2))};print $0}'
- résultat :
1 2 42698 44111624 2008-05-27 14:03:47 2 0 192.16.48.225 "95011" "95011" 0 17 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 44111628 2 0 192.16.224.0 "54790" "98500004" "" 0 0 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 1970-01-01 01:00:00 2008-05-27 14:03:48 "54790" "0aaaa261-d245-4264-b09d-6ac17129a5e4" "PBX_FR-PBX" "_Globals_DNs" "_Globals_DNs" "PBX_FR-PBX" 0 "SEP001E4AAAAAA7" "IPMA-RP" 12 0 1 1 18 18 0 "Cluster1" 1 "" "" 0 "" 3 1 0 0 0 0 ""
1 2 42699 44111631 2008-05-27 14:04:06 2 0 192.16.48.225 "95011" "95011" 0 1 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 44111632 0 0 0.0.0.0 "54576" "54576" "" 0 0 4 0.0.0.0 0 0 0 0 0 0 0 0.0.0.0 0 "0" "0" 1970-01-01 01:00:00 2008-05-27 14:04:07 "54576" "558aaaa5-225c-4f4c-a4df-9181e09c2f1f" "" "_Globals_DNs" "" "" 0 "SEP001E4AAAAAA7" "" 13 0 0 0 0 0 0 "Cluster1" 0 "" "" 0 "" 3 0 0 0 0 0 ""
1 2 42696 44111613 2008-05-27 14:01:14 2 0 192.16.28.203 "49240" "49240" 0 0 4 192.16.28.203 18454 4 20 0 0 0 0 0.0.0.0 0 "0" "0" 44111614 2 30 192.2.30.19 "00142148396" "00142148396" "" 0 16 4 192.2.30.19 18380 4 20 0 0 0 0 0.0.0.0 0 "0" "0" 2008-05-27 14:01:17 2008-05-27 14:04:28 "00142148396" "0abaaaa7-2990-48df-81d7-e9d015186857" "PBX_PSTN-FR-Granite" "_Globals_DNs" "PBX_PSTN-FR-Granite" "PBX_PSTN-FR" 191 "SEP001E7ACAAAA1" "S0/SU0/DS1-1@DEF-C50" 0 12 0 0 0 0 0 "Cluster1" 0 "" "" 0 "" 3 1 0 0 64 64 ""
Donc mes dates sont devenues lisibles, et les adresses ip aussi. :o)
Pour info :
- la fonction strtonum() marche bien aussi, cependant il aurait fallu l'écrire 4 fois pour envelopper les "0x" substr(ip,x,y), donc j'ai préféré réutiliser l'option --non-decimal-data qui marche chez moi et donne le même résultat.
- l'adresse ip en 0.12.1.46 venait du fait que la conversion en hexa du décimal 320733888 tient sur 7 digits, ce qui est a priori résolu en forçant le format de l'affichage avec sprintf("%8x",$(ipaddr[j])).
Un grand merci à tous les deux pour votre aide précieuse et pour le temps que vous avez bien voulu consacrer à mon problème !!!
Félicitations aussi pour votre maitrise de awk ;)
Nicooo
dubcek
Messages postés
18755
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
14 novembre 2024
5 621
3 févr. 2010 à 16:09
3 févr. 2010 à 16:09
- la fonction strtonum() marche bien aussi, cependant il aurait fallu l'écrire 4 fois pour
au post#11, j'ai mis une boucle : for(n=7;n>0;n-=2){printf("%d",strtonum("0x" substr(ip,n,2)))
visiblement, gawk traite les int sur 64bits, awk sur 32
au post#11, j'ai mis une boucle : for(n=7;n>0;n-=2){printf("%d",strtonum("0x" substr(ip,n,2)))
visiblement, gawk traite les int sur 64bits, awk sur 32
$ echo -1 | gawk '{printf("%u\n", $1)}' 18446744073709551615 $ echo -1 | awk '{printf("%u\n", $1)}' 4294967295 $
2 févr. 2010 à 11:08
par contre je maitrise pas un poil ce langage T_T