Modifier un fichier texte avec awk en bash... (Mac)
Résolu
MAMu_
Messages postés
48
Date d'inscription
Statut
Membre
Dernière intervention
-
dubcek Messages postés 18789 Date d'inscription Statut Contributeur Dernière intervention -
dubcek Messages postés 18789 Date d'inscription Statut Contributeur Dernière intervention -
A voir également:
- Gawk mac
- Adresse mac - Guide
- @ Sur mac - Guide
- Nettoyer son mac - Guide
- Temperature mac - Guide
- Mac os 15 - Accueil - MacOS
51 réponses
hello
je utiliserais awk plutôt que sed :
je utiliserais awk plutôt que sed :
$ awk 'BEGIN{FIELDWIDTHS="18 99"} !/^Name/ {gsub(" ", "", $1); printf "cmd%05d=%s;\nbutt%05d=%s;\n", ++n, $1, n, $2}' listfull.txt cmd00001=005; butt00001="005"; cmd00002=10yard; butt00002="10-Yard Fight (World, set 1)"; cmd00003=10yard85; butt00003="10-Yard Fight '85 (US, Taito license)"; cmd00004=10yardj; butt00004="10-Yard Fight (Japan)"; $
dubcek
Messages postés
18789
Date d'inscription
Statut
Contributeur
Dernière intervention
5 636
si awk sur Mac ne connait pas FIELDWIDTHS (c'est du gawk)
Salut,
awk est plus indiqué en effet, ne serait-ce que pour le formatage des nombres et la numérotation. Mais voici tout de même une possibilité de résolution avec sed :
Ca peut probablement se simplifier...
awk est plus indiqué en effet, ne serait-ce que pour le formatage des nombres et la numérotation. Mais voici tout de même une possibilité de résolution avec sed :
sed -n '/"/{=;p;}' listfull.txt | sed -n '{N;s/\n/ /;p;}' | sed 's/\(^[^ ]*\) \([^ ]*\) *\(.*\)$/cmd\1="\2";\nbutt\1=\3;/'
Ca peut probablement se simplifier...
Salut,
Une solution en bash :
Une solution en bash :
$ cat plop # Le fichier de départ 005 "005" 10yard "10-Yard Fight (World, set 1)" 10yard85 "10-Yard Fight '85 (US, Taito license)" 10yardj "10-Yard Fight (Japan)" $ ./foo.sh # L'exécution du script $ cat bar # Le fichier en sortie cmd00001="005"; butt00001="005"; cmd00002="10yard"; butt00002="10-Yard Fight (World, set 1)"; cmd00003="10yard85"; butt00003="10-Yard Fight '85 (US, Taito license)"; cmd00004="10yardj"; butt00004="10-Yard Fight (Japan)"; $ cat foo.sh # Le script #! /bin/bash exec > bar i=1 while read nom des do n=$(printf "%05d" ${i}) echo -e "cmd${n}=\"${nom}\";\nbutt${n}=${des};" ((i++)) done < plop $
Franchement... euh, je ne sais que dire... Vous êtes des dieux, vraiment... Moi qui m'attendait à avoir un début de solution d'ici quelques jours, je me retrouve avec une solution "presque" parfaite en moins d'une heure... et le bash s'execute à une vitesse impressionante...
Alors pourquoi le "presque" parfaite...?
J'ai utilisé la méthode de dubcek, la toute dernière, que j'envoie dans un nouveau fichier texte à l'aide de > newlist.txt :
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=%s;\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > newlist.txt
Le résultat est presque parfait, en effet il manque juste les guillemets pour la premiere variable :
cmd00001=005;
butt00001="005";
Cela devrait être :
cmd00001="005";
butt00001="005";
Mais franchement, vu votre rapidité, un enorme merci à tous sans exceptions, je vais pas chippoter et je vais essayer de rajouter ces guillemets par moi même :)
1000 merci :)
Alors pourquoi le "presque" parfaite...?
J'ai utilisé la méthode de dubcek, la toute dernière, que j'envoie dans un nouveau fichier texte à l'aide de > newlist.txt :
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=%s;\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > newlist.txt
Le résultat est presque parfait, en effet il manque juste les guillemets pour la premiere variable :
cmd00001=005;
butt00001="005";
Cela devrait être :
cmd00001="005";
butt00001="005";
Mais franchement, vu votre rapidité, un enorme merci à tous sans exceptions, je vais pas chippoter et je vais essayer de rajouter ces guillemets par moi même :)
1000 merci :)
Bon désolé, après juré je vous embête plus (bien que, ne jamais dire fontaine, mais ca devrait être bon au final...)
Donc j'ai mon bash principal qui marche nickel jusqu'à l'étape 3, celui-ci fait dans l'ordre :
1- Extraire listfull.txt à partir de MAME.SDL, OK
2- transformer listfull.txt en "variables.txt" que je pourrais charger dans mon interface Flash..., OK, Encore merci à vous...
3- Creer un fichier "test.bash" qui reprend à peu près la 2e étape mais en plus simple... et même en plus simple, je galère... :/
4- Rendre "test.bash" executable avec un chmod +x, OK...
Voilà ce que mon 3 est supposé faire, me mettre dans un fichier fullbash.bash ces lignes :
./config.bash 005
./config.bash 10yard
./config.bash 10yard85
etc...
(le config.bash que j'ai déjà codé marche parfaitement, il est fort simple : il me crée un fichier $1.bash contenant une ligne de commande et le rend executable (ou $1 est donc 005, 10yard,...) la ligne de commande lance MAME avec les options et les variables d'environnement dont MAME a besoin)
J'ai donc essayé de modifier le code du 2 (celui que vous m'avez fourni) en ceci :
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "./config.bash %s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > test.bash
Et j'obtiens comme résultat (dommage, loupé), ceci :
./config.bash 1;
./config.bash 2;
./config.bash 3;
./config.bash 4;
./config.bash 5;
./config.bash 6;
./config.bash 7;
Bref, c'est pas encore ca...
Mon bash principal et ses 4 étapes actuellement :
# Where is MAME ? (ie /Users/prod/Desktop/MAME/mame)
var_dirMAME="/Users/prod/Desktop/MAME/mame"
#-----------------------------------------------------
# Create listfull.txt from mame SDL
$var_dirMAME -listfull > listfull.txt
# Modify listfull.txt in variables.txt usable with Flash
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=\"%s\";\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > variables.txt
# Modify listfull.txt in test.bash (all games bash creation)
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "config.bash %s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > test.bash
# test.bash is executable
chmod +x test.bash
Donc j'ai mon bash principal qui marche nickel jusqu'à l'étape 3, celui-ci fait dans l'ordre :
1- Extraire listfull.txt à partir de MAME.SDL, OK
2- transformer listfull.txt en "variables.txt" que je pourrais charger dans mon interface Flash..., OK, Encore merci à vous...
3- Creer un fichier "test.bash" qui reprend à peu près la 2e étape mais en plus simple... et même en plus simple, je galère... :/
4- Rendre "test.bash" executable avec un chmod +x, OK...
Voilà ce que mon 3 est supposé faire, me mettre dans un fichier fullbash.bash ces lignes :
./config.bash 005
./config.bash 10yard
./config.bash 10yard85
etc...
(le config.bash que j'ai déjà codé marche parfaitement, il est fort simple : il me crée un fichier $1.bash contenant une ligne de commande et le rend executable (ou $1 est donc 005, 10yard,...) la ligne de commande lance MAME avec les options et les variables d'environnement dont MAME a besoin)
J'ai donc essayé de modifier le code du 2 (celui que vous m'avez fourni) en ceci :
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "./config.bash %s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > test.bash
Et j'obtiens comme résultat (dommage, loupé), ceci :
./config.bash 1;
./config.bash 2;
./config.bash 3;
./config.bash 4;
./config.bash 5;
./config.bash 6;
./config.bash 7;
Bref, c'est pas encore ca...
Mon bash principal et ses 4 étapes actuellement :
# Where is MAME ? (ie /Users/prod/Desktop/MAME/mame)
var_dirMAME="/Users/prod/Desktop/MAME/mame"
#-----------------------------------------------------
# Create listfull.txt from mame SDL
$var_dirMAME -listfull > listfull.txt
# Modify listfull.txt in variables.txt usable with Flash
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=\"%s\";\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > variables.txt
# Modify listfull.txt in test.bash (all games bash creation)
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "config.bash %s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > test.bash
# test.bash is executable
chmod +x test.bash
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
santé ! après une petite bière, on trouve comment optimiser.
awk plus court :
awk plus court :
awk -F '[ ]+"' '!/^Name/ {printf "cmd%05d=\"%s\";\nbutt%05d=\"%s;\n", ++n, $1, n, $2}' listfull.txtou
awk -F '[ ]+"' '!/^Name/ {printf "./config.bash %s;\n", $1}' plop
un grand merci dubcek, marche nickel... :)
Par contre et là je m'éloigne un peu du sujet... mais à peine... Comme j'essaie de rendre mon Front end compatible PC et Mac, l'executable flash, ou l'app flash, ne changeant pas, je me suis penché sur gawk, l'equivalent de awk sur PC pour essayer d'obtenir les mêmes fichiers à l'identique... :/ et là courage... il me sort que "'" n'est pas accepté, j'ai beau essayer la commande -F pour la source, ca ne veut rien savoir... Bref, je galère (qui a dit encore une fois ^^?)
Donc si qqn est capable de me donner la concordance entre les deux lignes format bash :
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=\"%s\";\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > variables.txt
et
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "../config.bash %s\n", x}' listfull.txt > CREATEALLBASH.bash
(ou la variante plus courte de dubcek qui me sort egalement des erreurs quand je la passe sous gawk...)
en utilisant gawk (ou awk, pas trop compris la difference, les deux étant fourni dans le bin de gawk PC), franchement ca serait plus que bienvenue ^^
C'est clair que je pourrais fournir les fichiers mac légèrement modifié pour le PC... mais je préférerais qu'un utilisateur lambda, en lançant un batch sur PC, et ce quel que soit la nouvelle version de MAME, puisse obtenir de lui-même les fichiers dont mon Front-End a besoin... :/
Merci d'avance si qqn s'est déjà penché sur le sujet "awk>gawk"... :)
Par contre et là je m'éloigne un peu du sujet... mais à peine... Comme j'essaie de rendre mon Front end compatible PC et Mac, l'executable flash, ou l'app flash, ne changeant pas, je me suis penché sur gawk, l'equivalent de awk sur PC pour essayer d'obtenir les mêmes fichiers à l'identique... :/ et là courage... il me sort que "'" n'est pas accepté, j'ai beau essayer la commande -F pour la source, ca ne veut rien savoir... Bref, je galère (qui a dit encore une fois ^^?)
Donc si qqn est capable de me donner la concordance entre les deux lignes format bash :
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=\"%s\";\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}' listfull.txt > variables.txt
et
awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "../config.bash %s\n", x}' listfull.txt > CREATEALLBASH.bash
(ou la variante plus courte de dubcek qui me sort egalement des erreurs quand je la passe sous gawk...)
en utilisant gawk (ou awk, pas trop compris la difference, les deux étant fourni dans le bin de gawk PC), franchement ca serait plus que bienvenue ^^
C'est clair que je pourrais fournir les fichiers mac légèrement modifié pour le PC... mais je préférerais qu'un utilisateur lambda, en lançant un batch sur PC, et ce quel que soit la nouvelle version de MAME, puisse obtenir de lui-même les fichiers dont mon Front-End a besoin... :/
Merci d'avance si qqn s'est déjà penché sur le sujet "awk>gawk"... :)
awk ou gawk sur PC en ligne de commande, c'est le bagne à cause des " ' $ et autres, utiliser un fichier de commande, fonctionne partout:
awk -f fichier.txt listfull.txt > variables.txt cat ou type fichier.txt !/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "cmd%05d=\"%s\";\nbutt%05d=%s;\n", ++n, x, n, substr($0, 19)}
Puis-je encore abuser de votre temps et poser encore une question pour awk...?
En gros voilà, tout marche bien comme prévu dans le developpement de mon FE, mais malheureusement le listfull.txt que je traite n'est pas assez complet pour recuperer toutes les données et variables dont j'ai besoin selon les choix de l'utilisateur...
Donc je me suis tourné vers le MAME -listXML qui lui me sort un fichier bien plus complet avec toutes les variables dont je pourrais avoir besoin, mais qui est le XML le plus barré que je connaisse ^^...
Je l'ai regardé avec Advanced XML converter pour voir un peu son arborescence... et il est bien barbare...
Ci joint le fichier XML en sortie de MAME... :
http://zemamu.free.fr/listfull.xml.zip
Exactement sur la même construction que la sortie de mon listfull.txt, je voudrais récupérer un fichier qui commencerait par :
MAMEver="0.148u2 (Mar 19 2013)";
et ensuite viendraient mes variables à charger dans flash toujours avec le même système d'incrementation pour chaques entrées... (ici exemple 10yard, la 2e entrée...)
name000002="10Yard";
sourcefile000002="m58.c";
ismechanical000002="yes";
cloneof000002="10yard";
description000002="10-Yard Fight (World, set 1)";
year000002="1983";
manufacturer000002="Irem";
//Les 2 lignes 'ismechanical="yes" et "cloneof" ne sont pas présentes à tous les coups,
//elles ne sont pas là pour 10yard, mais comme il me les faut si elles sont présentes...
type000002="raster";
rotate000002="0";
width000002="256";
height000002="224";
status000002="good";
emulation000002="good";
color000002="good";
sound000002="good";
graphic000002="good";
//Ces valeurs ci dessus sont vers la fin de chaque entrée
Croyez vous que vous pourriez encore une fois me donner ce coup de main...?
Ou au moins m'indiquer la voie pour traiter les 4/5 premieres lignes, et ensuite j'essaierai d'appliquer par moi-même... Mais c'est vraiment des lignes de commandes de barbare awk quand on découvre... ^^
Sincèrement, Aymeric...
En gros voilà, tout marche bien comme prévu dans le developpement de mon FE, mais malheureusement le listfull.txt que je traite n'est pas assez complet pour recuperer toutes les données et variables dont j'ai besoin selon les choix de l'utilisateur...
Donc je me suis tourné vers le MAME -listXML qui lui me sort un fichier bien plus complet avec toutes les variables dont je pourrais avoir besoin, mais qui est le XML le plus barré que je connaisse ^^...
Je l'ai regardé avec Advanced XML converter pour voir un peu son arborescence... et il est bien barbare...
Ci joint le fichier XML en sortie de MAME... :
http://zemamu.free.fr/listfull.xml.zip
Exactement sur la même construction que la sortie de mon listfull.txt, je voudrais récupérer un fichier qui commencerait par :
MAMEver="0.148u2 (Mar 19 2013)";
et ensuite viendraient mes variables à charger dans flash toujours avec le même système d'incrementation pour chaques entrées... (ici exemple 10yard, la 2e entrée...)
name000002="10Yard";
sourcefile000002="m58.c";
ismechanical000002="yes";
cloneof000002="10yard";
description000002="10-Yard Fight (World, set 1)";
year000002="1983";
manufacturer000002="Irem";
//Les 2 lignes 'ismechanical="yes" et "cloneof" ne sont pas présentes à tous les coups,
//elles ne sont pas là pour 10yard, mais comme il me les faut si elles sont présentes...
type000002="raster";
rotate000002="0";
width000002="256";
height000002="224";
status000002="good";
emulation000002="good";
color000002="good";
sound000002="good";
graphic000002="good";
//Ces valeurs ci dessus sont vers la fin de chaque entrée
Croyez vous que vous pourriez encore une fois me donner ce coup de main...?
Ou au moins m'indiquer la voie pour traiter les 4/5 premieres lignes, et ensuite j'essaierai d'appliquer par moi-même... Mais c'est vraiment des lignes de commandes de barbare awk quand on découvre... ^^
Sincèrement, Aymeric...
si je résume il faut extraire des balise <game> </game> ces variables : name|sourcefile|ismechanical|cloneof|description|year|manufacturer
type|rotate|width|height|status|emulation|color|sound|graphic
et les afficher sous la forme : <nom><compteur>="<valeur>";
type|rotate|width|height|status|emulation|color|sound|graphic
et les afficher sous la forme : <nom><compteur>="<valeur>";
j'aurais pas u l'exprimer aussi simplement et si court, mais c'est exactement ca :)
sachant que les variables "ismechanical" et "cloneof" ne sont pas presentes à tous les coups dans toutes les balises <game>, et peut être d'autres d'ailleurs (un jeu type raster a une resolution alors qu'un vector game n'en a pas)...
Si la variable n'existe pas, ne pas la lister ou la lister avec <valeur> = null, indifferement... car au final tester si la variable existe ou si elle est egale à NULL dans mon projet reviens au même...
Si la variable n'existe pas, ne pas la lister ou la lister avec <valeur> = null, indifferement... car au final tester si la variable existe ou si elle est egale à NULL dans mon projet reviens au même...
essayer ce code
$ cat a0.awk /<game name=/ {c1=";"; c2=";\n"; ns=sprintf("%05d", ++n) gsub("=", ns "="); sub(">", ""); print $2 c1 if($3 ~ /sourcefile/)print $3 c1 if($4 ~ /ismechanical|cloneof/)print $4 c1 if($5 ~ /ismechanical|cloneof/)print $5 c1} /<description>|<year>|<manufacturer>/ {split($0, t, "[<>]") print t[2] ns "=\"" t[3] "\"" c1} /<display/ {gsub("=", ns "="); print $3 c2 $4 c1 if($5 ~ /width|height/)print $5 c1 if($6 ~ /width|height/)print $6 c1} /<driver/ {gsub("=", ns "="); print $2 c2 $3 c2 $4 c2 $5 c2 $6 c1} $ $ awk -f a0.awk listfull.xml > variables.txt $ $ head -20 variables.txt name00001="005"; sourcefile00001="segag80r.c"; description00001="005"; year00001="1981"; manufacturer00001="Sega"; type00001="raster"; rotate00001="270"; width00001="256"; height00001="224"; status00001="imperfect"; emulation00001="good"; color00001="good"; sound00001="imperfect"; graphic00001="good"; name00002="10yard"; sourcefile00002="m58.c"; description00002="10-Yard Fight (World, set 1)"; year00002="1983"; manufacturer00002="Irem"; type00002="raster"; $
il y avait un bug, il manquait certains height = en fin de balise, ceci corrige et est plus dense:
BEGIN {FS="[ \t>]+"; v="name=|sourcefile=|ismechanical=|cloneof=|type=|rotate=|width=|height=|status=|emulation=|color=|sound=|graphic=" ; c=";"} /<game / {ns=sprintf("%05d", ++n)} /<game |<display |<driver / {for(f=2; f<=NF; f++)if($f ~ v){sub("=", ns "=", $f); print $f c }} /<description>|<year>|<manufacturer>/ {split($0, t, "[<>]"); print t[2] ns "=\"" t[3] "\"" c}
Mouarf j'avais même pas vu, merci beaucoup :)
En fait j'ai du changer et adapter légérement le code (l'ancien, je vais regarder le nouveau) pour que ce soit compatible 'variables' en chargement externe sous Flash... Mais pas de soucis, m'en suit sorti en repassant 2 fois à la moulinette awk et sed (comme quoi j'avance et je commence à comprendre) le fichier de sortie de ton code :)
Avant:
var00001="aaaa";
var00002="bbbb";
var00003="cccc";
...
Maintenant:
var00001=aaaa&var00002=bbbb&var00003=cccc&...
pas besoin de guillemets (alors que dans Flash ils sont obligatoires, en chargement externe je les retrouvais dans mon champ texte, et le ";" plus passage à la ligne n'est pas reconnu en chargement externe, il faut direct un "&" et on passe de suite à la variable suivante... (Ca peut servir pour certains qui voudraient faire ce genre de manip variables declarées en externe > import en Flash)
Enfin, merci en tout cas, 1000 fois :)
En fait j'ai du changer et adapter légérement le code (l'ancien, je vais regarder le nouveau) pour que ce soit compatible 'variables' en chargement externe sous Flash... Mais pas de soucis, m'en suit sorti en repassant 2 fois à la moulinette awk et sed (comme quoi j'avance et je commence à comprendre) le fichier de sortie de ton code :)
Avant:
var00001="aaaa";
var00002="bbbb";
var00003="cccc";
...
Maintenant:
var00001=aaaa&var00002=bbbb&var00003=cccc&...
pas besoin de guillemets (alors que dans Flash ils sont obligatoires, en chargement externe je les retrouvais dans mon champ texte, et le ";" plus passage à la ligne n'est pas reconnu en chargement externe, il faut direct un "&" et on passe de suite à la variable suivante... (Ca peut servir pour certains qui voudraient faire ce genre de manip variables declarées en externe > import en Flash)
Enfin, merci en tout cas, 1000 fois :)
Je reviens à l'attaque... comme expliqué dans mon post précédent (désolé j'aurais du tester avant...) le fichier que je doit recuperer en sortie doit se présenter ainsi : var00001=aaaa&var00002=bbbb&var00003=cccc&... et non plus tout à la ligne avec ";" comme séparateur mais "&", et plus besoin de guillemets...
Je fait donc une fois ton code awk éfféctué les opérations suivantes sur le fichier variables.txt obtenu :
awk -f ext2.awk variables.txt > variables2.txt
sed -i "s/\"//g" variables2.txt
avec ext2.awk : BEGIN {ORS=""} {print} END {print "\n"}
Je remplace donc tous les retours à la ligne (\n) par du vide...
et sed me supprime donc tous les guillemets... (pour le & j'avais directement tapé dans ton ancien code en remplacant les ";" par "&", nickel...)
J'obtiens donc le bon résultat, mais en plus d'étapes... :)
Mais comme j'aime bien les trucs carrés, j'ai essayé de faire pareil mais uniquement avec ton code, soit en une seule étape...
BEGIN {FS="[ \t>]+"; v="name=|sourcefile=|ismechanical=|cloneof=|type=|rotate=|width=|height=|status=|emulation=|color=|sound=|graphic=" ; c=";"}
/<game / {ns=sprintf("%05d", ++n)}
/<game |<display |<driver / {for(f=2; f<=NF; f++)if($f ~ v){sub("=", ns "=", $f); print $f c }}
/<description>|<year>|<manufacturer>/ {split($0, t, "[<>]"); print t[2] ns "=\"" t[3] "\"" c}
Bon sur la dernière ligne, enlever les guillemets \" à la fin, ok...: "=" t[3] "" c}
ca m'enlève bien les guillemets pour les champs description, year, manufacturer... OK
Pour afficher un & en fin de chaque lignes, je modifie sur la première ligne c=";" par c="&"... ca marche parfaitement...
et voilà...
Il me reste donc à réussir à enlever les guillemets pour tous les autres champs, et à réussir à supprimer les retours à la ligne... et je ne réussis pas... cela doit pourtant bien être faisable...
Ton code avec mes modifs en l'état:
BEGIN {FS="[ \t>]+"; v="name=|sourcefile=|ismechanical=|cloneof=|type=|rotate=|width=|height=|status=|emulation=|color=|sound=|graphic=" ; c="&"} {ORS=""} {print} END {print "\n"}
/<game |<display |<driver / {for(f=2; f<=NF; f++)if($f ~ v){sub("=", ns "=", $f); print $f c }}
/<description>|<year>|<manufacturer>/ {split($0, t, "[<>]"); print t[2] ns "=" t[3] "" c}
Si tu vois comment réussir pour les guillemets restant et les retours lignes avec une commande awk compléte et non pas 2 awk et 1 sed comme je fait... volontiers ;)
Merci d'avance...
Je fait donc une fois ton code awk éfféctué les opérations suivantes sur le fichier variables.txt obtenu :
awk -f ext2.awk variables.txt > variables2.txt
sed -i "s/\"//g" variables2.txt
avec ext2.awk : BEGIN {ORS=""} {print} END {print "\n"}
Je remplace donc tous les retours à la ligne (\n) par du vide...
et sed me supprime donc tous les guillemets... (pour le & j'avais directement tapé dans ton ancien code en remplacant les ";" par "&", nickel...)
J'obtiens donc le bon résultat, mais en plus d'étapes... :)
Mais comme j'aime bien les trucs carrés, j'ai essayé de faire pareil mais uniquement avec ton code, soit en une seule étape...
BEGIN {FS="[ \t>]+"; v="name=|sourcefile=|ismechanical=|cloneof=|type=|rotate=|width=|height=|status=|emulation=|color=|sound=|graphic=" ; c=";"}
/<game / {ns=sprintf("%05d", ++n)}
/<game |<display |<driver / {for(f=2; f<=NF; f++)if($f ~ v){sub("=", ns "=", $f); print $f c }}
/<description>|<year>|<manufacturer>/ {split($0, t, "[<>]"); print t[2] ns "=\"" t[3] "\"" c}
Bon sur la dernière ligne, enlever les guillemets \" à la fin, ok...: "=" t[3] "" c}
ca m'enlève bien les guillemets pour les champs description, year, manufacturer... OK
Pour afficher un & en fin de chaque lignes, je modifie sur la première ligne c=";" par c="&"... ca marche parfaitement...
et voilà...
Il me reste donc à réussir à enlever les guillemets pour tous les autres champs, et à réussir à supprimer les retours à la ligne... et je ne réussis pas... cela doit pourtant bien être faisable...
Ton code avec mes modifs en l'état:
BEGIN {FS="[ \t>]+"; v="name=|sourcefile=|ismechanical=|cloneof=|type=|rotate=|width=|height=|status=|emulation=|color=|sound=|graphic=" ; c="&"} {ORS=""} {print} END {print "\n"}
/<game |<display |<driver / {for(f=2; f<=NF; f++)if($f ~ v){sub("=", ns "=", $f); print $f c }}
/<description>|<year>|<manufacturer>/ {split($0, t, "[<>]"); print t[2] ns "=" t[3] "" c}
Si tu vois comment réussir pour les guillemets restant et les retours lignes avec une commande awk compléte et non pas 2 awk et 1 sed comme je fait... volontiers ;)
Merci d'avance...
tout le fichier sur une seule ligne ou une ligne par balise <game name= ?
et il y a des balise <description> et d'autres qui contiennent des &, ca peut être un problème, non ?
et il y a des balise <description> et d'autres qui contiennent des &, ca peut être un problème, non ?
Bien vu.. je viens de faire un test dans flash en chargeant la variable description00529=Panel & Variety Akamaru Q Jousyou Dont-R et en effet je ne charge que Panel... il faut donc modifier en amont tous les signes &, <, etc par and, <...
Bon je pense que plusieurs etapes vont donc quand même être indispensables...
Je vais faire plus de test ^^
Merci
Bon je pense que plusieurs etapes vont donc quand même être indispensables...
Je vais faire plus de test ^^
Merci
essaye ca
gsub supprime les "
% est traité comme format (par ex :%d) par printf, pas un double : %%
BEGIN {FS="[ \t>]+"; v="name=|sourcefile=|ismechanical=|cloneof=|type=|rotate=|width=|height=|status=|emulation=|color=|sound=|graphic=" ; c="&"} /<game / {ns=sprintf("%05d", ++n)} /<game |<display |<driver / {for(f=2; f<=NF; f++){if($f ~ v){sub("=", ns "=", $f); gsub("\"", "", $f); printf $f c }}} /<description>|<year>|<manufacturer>/ {gsub("%", "%%"); gsub("&", "and"); split($0, t, "[<>]"); printf t[2] ns "=" t[3] c}printf au lieu de print n'ajoute pas de \n
gsub supprime les "
% est traité comme format (par ex :%d) par printf, pas un double : %%
pfff plus ca avance et plus je me retrouve face à des difficultés inattendues même si ca avance très vite grace à toi... :
Je n'ai pas encore essayé ton code car le nouvel écueil se situe en amont à mon avis, avant la numérotation...:
Je tire correctement toutes mes variables, et les affichent bien dans mon projet flash qui en analysent même certaines pour afficher des images au lieu de la valeur texte (ex logos manufacturer)...
mais la liste des variables commençant par name, puis description (voir copie suivante après ta moulinette (pas modifié les retours à la lignes, ni les "< > & ' "), je n'obtiens pas les variables dans l'ordre alphabétique de (description), ce qui n'est pas top, mais dans l'ordre alphabétique des shorts names de fichiers (name...)
Donc si je comprends bien... ma nouvelle moulinette que je vais essayer de faire par moi-même grace à toute ton aide et à tes dernieres indications, toujours en multipasse pour l'instant, plus simple pour apprendre... ^^ :
il faudrait que je réussisse "avant numérotation"...
1) à faire une seule ligne pour chaque groupe de variables, chaque nouvelle ligne commencant par name=.... en modifiant ton awk, je doit pouvoir réussir à faire ca..
name=005;sourcefile=....description=....
2) réussir à inverser dans chaque ligne le champ "name=<value>" et le champ"description=<value>...
3) faire un sort sur le fichier obtenu...
4) remettre la numérotation qui s'incremente à chaque nouvelle description= pour toutes les variables possibles de chaque ligne...*
5) remettre en une seule ligne...
Je ne sais pas si réfléchir à haute voix sur le forum est accepté, mais je me suis dit que toute cette reflection : projet, problème, solution pourrait être utile pour d'autres... :)
*peut être ce qui va être le plus difficile pour moi... :)
Je n'ai pas encore essayé ton code car le nouvel écueil se situe en amont à mon avis, avant la numérotation...:
Je tire correctement toutes mes variables, et les affichent bien dans mon projet flash qui en analysent même certaines pour afficher des images au lieu de la valeur texte (ex logos manufacturer)...
mais la liste des variables commençant par name, puis description (voir copie suivante après ta moulinette (pas modifié les retours à la lignes, ni les "< > & ' "), je n'obtiens pas les variables dans l'ordre alphabétique de (description), ce qui n'est pas top, mais dans l'ordre alphabétique des shorts names de fichiers (name...)
Donc si je comprends bien... ma nouvelle moulinette que je vais essayer de faire par moi-même grace à toute ton aide et à tes dernieres indications, toujours en multipasse pour l'instant, plus simple pour apprendre... ^^ :
il faudrait que je réussisse "avant numérotation"...
1) à faire une seule ligne pour chaque groupe de variables, chaque nouvelle ligne commencant par name=.... en modifiant ton awk, je doit pouvoir réussir à faire ca..
name=005;sourcefile=....description=....
2) réussir à inverser dans chaque ligne le champ "name=<value>" et le champ"description=<value>...
3) faire un sort sur le fichier obtenu...
4) remettre la numérotation qui s'incremente à chaque nouvelle description= pour toutes les variables possibles de chaque ligne...*
5) remettre en une seule ligne...
Je ne sais pas si réfléchir à haute voix sur le forum est accepté, mais je me suis dit que toute cette reflection : projet, problème, solution pourrait être utile pour d'autres... :)
*peut être ce qui va être le plus difficile pour moi... :)