Modifier un fichier texte avec awk en bash... (Mac)

Résolu/Fermé
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013 - 3 avril 2013 à 16:02
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 - 26 mai 2013 à 10:22
Bonjour, pour la réalisation d'un frontend pour MAME SDL au format Mac, en projo flash local, je cherche à modifier les fichiers de sorties de MAME en bash avec sed...

Mon fichier listfull.txt (mame -listfull > listfull.txt) en sortie de MAME se présente ainsi (le nombre d'espaces, remplacés ici par des _ pour une lecture plus proche de la réalité, entre les noms et les descriptions varient, mais le premier " est toujours le 19e charactere de la ligne...) :

Name:_____________Description:
005_______________"005"
10yard____________"10-Yard Fight (World, set 1)"
10yard85__________"10-Yard Fight '85 (US, Taito license)"
10yardj___________"10-Yard Fight (Japan)"

Mon but est de transformer donc ces lignes en :

cmd00001="005";
butt00001="005";
cmd00002="10yard";
butt00002="10-Yard Fight (World, set 1)";
cmd00003="10yard85";
butt00003="10-Yard Fight '85 (US, Taito license)";
etc...

De manière à pouvoir les injecter sous forme de variables dans Flash...
Et franchement, j'avoue avoir de sérieuses lacunes, balbutiant en bash et surtout découvrant sed, qui me semble être la bonne voie pour atteindre mon but...

D'avance merci, toutes aides, explications, solutions (voir autre methode*) seront les bienvenues...
* pas de php, uniquement qu'en bash, mon projet étant un frontend local et étant de plus limité également par ce qu'accepte de lancer flash localement via un bouton...)

Sincèrement, MAMu_
A voir également:

51 réponses

dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
3 avril 2013 à 16:40
hello
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)";
$ 
1
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
3 avril 2013 à 17:08
si awk sur Mac ne connait pas FIELDWIDTHS (c'est du gawk)
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
0
totof31 Messages postés 163 Date d'inscription lundi 29 octobre 2012 Statut Membre Dernière intervention 30 avril 2013 74
3 avril 2013 à 16:56
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 :

sed -n '/"/{=;p;}' listfull.txt | sed -n '{N;s/\n/ /;p;}' | sed 's/\(^[^ ]*\) \([^ ]*\) *\(.*\)$/cmd\1="\2";\nbutt\1=\3;/'


Ca peut probablement se simplifier...
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
3 avril 2013 à 16:57
Salut,

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

$

0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
3 avril 2013 à 17:24
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 :)
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
3 avril 2013 à 17:28
printf "cmd%05d=\"%s\";\nbutt%05d=%s;\n"
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
3 avril 2013 à 17:36
MERCI zipe31... j'étais justement en train d'essayer de déchiffrer la fameuse ligne de commande ^^

Je suis sur le c... Bravo et merci à vous tous :)
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
3 avril 2013 à 18:23
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
0
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 407
3 avril 2013 à 18:43
$ awk '!/^Name/ {x=substr($0,1 ,18); gsub(" ", "", x); printf "./config.bash %s;\n", x}' plop 
./config.bash 005;
./config.bash 10yard;
./config.bash 10yard85;
./config.bash 10yardj;

$
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
3 avril 2013 à 19:07
Encore merci... :)
Je teste ca de suite :)

Et bien évidement, ca marche nickel... :)
Merci merci merci :)
Je marque ce sujet comme RESOLU.. :)

Si t'es dans le 06, je te paie une bière avec grand plaisir :)
0

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

Posez votre question
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
3 avril 2013 à 19:43
santé ! après une petite bière, on trouve comment optimiser.
awk plus court :
awk -F '[ ]+"' '!/^Name/ {printf "cmd%05d=\"%s\";\nbutt%05d=\"%s;\n", ++n, $1, n, $2}' listfull.txt
ou
awk -F '[ ]+"' '!/^Name/ {printf "./config.bash %s;\n", $1}' plop 
0
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"... :)
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 9/04/2013 à 10:13
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)}
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
12 avril 2013 à 13:23
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...
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
12 avril 2013 à 14:50
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>";
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
12 avril 2013 à 17:13
j'aurais pas u l'exprimer aussi simplement et si court, mais c'est exactement ca :)
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
12 avril 2013 à 17:20
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...
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 14/04/2013 à 14:51
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"; 
$ 
0
Merci encore dubcek... :) marche parfaitement bien
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 16/04/2013 à 10:44
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}
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
16 avril 2013 à 17:19
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 :)
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
17 avril 2013 à 15:17
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...
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 17/04/2013 à 16:10
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 ?
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
17 avril 2013 à 21:03
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
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
17 avril 2013 à 21:05
"& amp", "& lt"... ;) sans espaces... le forum les interprete bien lui en tout cas... enfin rechercher toutes les occurrences du symbole & selon situation...
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
17 avril 2013 à 22:36
bon j'obtiens un resultat correct, mais en 7 étapes : 2 awk & 5 sed...
C'est pas super propre mais le résultat est là...

Merci pour toute ton aide
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
18 avril 2013 à 08:17
essaye ca
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 : %%
0
MAMu_ Messages postés 48 Date d'inscription mercredi 3 avril 2013 Statut Membre Dernière intervention 25 mai 2013
18 avril 2013 à 15:20
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... :)
0
dubcek Messages postés 18718 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 22 mars 2024 5 615
Modifié par dubcek le 18/04/2013 à 15:37
pourquoi faire un sort sur le fichier ?
pour insérer un saut de ligne avant chaque name, je ferai, avec mon code:
/<game / {ns=sprintf("%05d", ++n); if(nl++)print ""}
le test est pour éviter un \n avant le premier name=
0