#1 Le 06/10/2017, à 09:48
- Mornagest
[Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Salut les gens,
Je suis sûr que mon titre est tout sauf clair, je vais donc vous donner un échantillon de ce que je souhaite faire.
@1006707=~Fléau +1~
@1006709=~La masse descend directement du simple gourdin. C'est une simple hampe de bois avec une tête en pierre ou en fer fixée à son extrémité. La forme de la tête varie : certaines sont pointues, d'autres à rebord, d'autres encore sont pyramidales.
PARAMÈTRES :
Dégâts : 1d6 +1
Type de dégâts : contondant
Poids : 10
Facteur de vitesse : 7
Type de compétence : masse
Type : arme à 1 main
Force nécessaire : 10
Non utilisable par :
Druide
Mage
Voleur
Moine
Belluaire~
@1006710=~Masse +1~
Chaque ligne avec @123456=~blabla~ représente une ligne de "dialogue" dans un jeu (Baldur's Gate, pour ne pas le nommer), mais au sein de ces lignes, on voit clairement qu'il y a d'autres lignes, dont certaines sont vides.
Je ne peux donc pas trier ces lignes par ordre numérique avec sort -n, car sinon, toutes les lignes vides vont se retrouver ensemble... puis toutes les lignes PARAMÈTRES :, etc.
J'ai essayé de contourner le souci en modifiant les retours à la ligne par des mots (\r\n devient GROPOUET par exemple), mais le fichier à traiter est énorme (2,6 Mo actuellement) et certaines lignes sautent (du genre, un millier de lignes disparaissent ).
Pourquoi trier, me direz-vous ? Parce que c'est bien plus commode : j'ajoute régulièrement des lignes, et leur numéro n'est pas de mon fait, il faut que je réutilise celui du jeu. Or, je les ajoute en les insérant à chaque fois au bon endroit dans le fichier. Mais là, par exemple, j'ai 900 lignes à réinsérer dans un fichier qui en contient déjà plus de 9000, alors, à la main, ça va me prendre des heures. Je préférerais les copier-coller à la fin puis tout retrier...
Voilà, je ne sais pas si c'est très clair ; sinon, dites-moi et j'essaierai d'être plus explicite.
Merci d'avance pour vos réponses
Dernière modification par Mornagest (Le 06/10/2017, à 18:04)
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#2 Le 06/10/2017, à 10:15
- pingouinux
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Bonjour,
Si j'ai bien compris, lors du tri, tu veux déplacer comme un seul bloc la ligne commençant par @xxxxxxx=~ et celles qui suivent. Est-ce bien ça ?
Hors ligne
#3 Le 06/10/2017, à 10:31
- Mornagest
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Voilà, c'est exactement ça. Un bloc qui va du @123456=~ et qui s'achève par le second ~
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#4 Le 06/10/2017, à 10:47
- pingouinux
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Je ne comprends pas. Le second ~ se trouve sur la même ligne que @123456=~. Que fais-tu des lignes qui n'ont pas ce format ?
Donne éventuellement un exemple.
Hors ligne
#5 Le 06/10/2017, à 13:10
- Mornagest
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
J'imagine que ce n'est pas évident, mes explications ne sont pas forcément très claires
sort considère une ligne comme celle-ci :
@123456=~blabla~
comme une ligne à part entière, ce qui est correct.
Mais quand j'ai une ligne qui fait
@123456=~blabla
blibli
bloblo~
il considère que
@123456=~blabla
blibli
bloblo~
sont trois lignes distinctes, et va donc les classer par ordre alphabétique entre elles.
Je voudrais qu'il puisse considérer qu'une ligne soit comprise entre le @ et le ~ final, si c'est possible.
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#6 Le 06/10/2017, à 13:27
- pingouinux
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Ça y est, j'ai pigé !
Tu peux essayer mon_script.py (c'est du python).
#!/usr/bin/python
import sys, re
resul={}
rec_bloc=re.compile('^(@(\d+)=~[^~]+~\n)',re.M)
blocs=rec_bloc.findall(sys.stdin.read())
for bloc in blocs: resul[bloc[1]]=bloc[0]
for bloc in sorted(resul.keys(),key=lambda x:int(x)): sys.stdout.write(resul[bloc])
À appeler ainsi
./mon_script.py <fichier_original >fichier_trie
Ajouté : Plus simple
#!/usr/bin/python
import sys, re
rec_bloc=re.compile('^(@(\d+)=~[^~]+~\n)',re.M)
blocs=rec_bloc.findall(sys.stdin.read())
blocs.sort(key=lambda x:int(x[1]))
for bloc in blocs: sys.stdout.write(bloc[0])
Dernière modification par pingouinux (Le 06/10/2017, à 13:33)
Hors ligne
#7 Le 06/10/2017, à 13:39
- Mornagest
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Merci
Je viens de tenter, mais il sort un fichier vierge pour l'instant je me disais bien aussi que le terminal me rendait la main un peu rapidement...
(bon, étant une quiche en Python, je suis bien incapable de déceler une éventuelle erreur dans ton script)
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#8 Le 06/10/2017, à 13:53
- LeoMajor
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
bonjour,
awk 'BEGIN { RS="~\n"; FS="~"; }; {gsub(/[\n]/," ",$2);items[$2]=$1}; END {print "END"; for(item in items){c++; printf("%d %s~%s~\n",c,items[item],item) }}' /tmp/test.log
END
1 @1006707=~Fléau +1~
2 @1006709=~La masse descend directement du simple gourdin. C'est une simple hampe de bois avec une tête en pierre ou en fer fixée à son extrémité. La forme de la tête varie : certaines sont pointues, d'autres à rebord, d'autres encore sont pyramidales. PARAMÈTRES : Dégâts : 1d6 +1 Type de dégâts : contondant Poids : 10 Facteur de vitesse : 7 Type de compétence : masse Type : arme à 1 main Force nécessaire : 10 Non utilisable par : Druide Mage Voleur Moine Belluaire~
3 @1006710=~Masse +1~
tu enlèves le gsub si tu ne veux pas la forme compactée.
Hors ligne
#9 Le 06/10/2017, à 14:01
- Mornagest
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Salut LeoMajor,
J'ai tenté, mais je ne sais pas pourquoi, le script ne s'occupe que de la première ligne du fichier, ensuite, il s'arrête et j'ai de nouveau la main sur le terminal...
awk 'BEGIN { RS="~\n"; FS="~"; }; {gsub(/[\n]/," ",$2);items[$2]=$1}; END {print "END"; for(item in items){c++; printf("%d %s~%s~\n",c,items[item],item) }}' correcfr.tra | tee testawk.tra
END
1 @1000001=~Non, dsol, a ne me dit rien.~
(les caractères spéciaux, c'est parce que mon fichier est en encodage windows-1252 pour être compatible avec le jeu, c'est normal)
D'autre part, et je suis vraiment désolé, je me rends compte que j'ai évidemment des exceptions dans ce gros fichier
Certaines lignes sont déclinées au masculin ET au féminin (les dialogues peuvent concerner le personnage principal, celui qu'on joue, et qui peut donc être un homme ou une femme).
Il y a donc des lignes sous la forme
@1000001=~Non, désolé, ça ne me dit rien.~ ~Non, désolée, ça ne me dit rien.~
J'imagine que ça doit pouvoir être pris en compte...
Merci pour votre aide, c'est sympa !
Dernière modification par Mornagest (Le 06/10/2017, à 14:02)
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#10 Le 06/10/2017, à 15:43
- pingouinux
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Je viens de voir ceci, dans ton message #1 :
J'ai essayé de contourner le souci en modifiant les retours à la ligne par des mots (\r\n devient GROPOUET par exemple),
Mon script suppose que tes lignes se terminent par '\n' et non par '\r\n'.
Essaye ceci :
#!/usr/bin/python
import sys, re
rec_bloc=re.compile('^(@(\d+)=~[^~]+~\r?\n)',re.M)
blocs=rec_bloc.findall(sys.stdin.read())
blocs.sort(key=lambda x:int(x[1]))
for bloc in blocs: sys.stdout.write(bloc[0])
Hors ligne
#11 Le 06/10/2017, à 16:05
- pingouinux
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Il y a donc des lignes sous la forme
@1000001=~Non, désolé, ça ne me dit rien.~ ~Non, désolée, ça ne me dit rien.~
Évidemment, si tu changes les spécifications au fur et à mesure…
#!/usr/bin/python
import sys, re
rec_bloc=re.compile('^(@(\d+)=~.+?~\r?\n)',re.M|re.S)
blocs=rec_bloc.findall(sys.stdin.read())
blocs.sort(key=lambda x:int(x[1]))
for bloc in blocs: sys.stdout.write(bloc[0])
Dernière modification par pingouinux (Le 06/10/2017, à 16:05)
Hors ligne
#12 Le 06/10/2017, à 18:04
- Mornagest
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Oui, je sais, c'est ma faute, j'y pensais plus
Je viens de faire le test avec ta dernière version, et ça fonctionne parfaitement ! un tout grand merci à toi, Pingouinux !
Je passe en [résolu]
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne
#13 Le 07/10/2017, à 11:15
- Mornagest
Re : [Résolu] Tri de lignes au sein desquelles il y a des lignes vides
Suite à une remarque d'un de mes camarades qui suit cette affaire de fichiers de dialogues (Isaya, pour ne pas le nommer), il a modifié le script pour tenir compte de certains cas particuliers dans le fichier (des balises [ ] que j'avais également oubliées... décidément !).
Voici donc la version définitive que j'ai testée et qui fonctionne pour tous les cas qui me tracassaient (ça peut toujours servir de base pour quelqu'un d'autre !)
#!/usr/bin/python
import sys, re
rec_bloc=re.compile('^(@(\d+)[ ]*=[ ]*~.+?~[ ]*(\[[^\]]+\])*[ ]*\r?\n)',re.M|re.S)
blocs=rec_bloc.findall(sys.stdin.read())
blocs.sort(key=lambda x:int(x[1]))
for bloc in blocs: sys.stdout.write(bloc[0])
Dernière modification par Mornagest (Le 07/10/2017, à 11:16)
N'oubliez pas de consulter la documentation pour vous donner un coup de main !
Merci de modifier le premier message de votre sujet pour ajouter [Résolu] lorsque votre problème l'est :)
Xubuntu 20.04 sur deux ordinateurs, zéro souci. Passez à Xubuntu ;)
Hors ligne