Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 15/08/2014, à 17:47

Le Goss

[Résolu] Bash: sed n'interpréter que certaines parties du fichier

Bonjour à tous,

Je cherche à écrire un script qui me permettrait de créer des documents dans lesquels s'alterneraient 2 langues différentes: français et grec ancien.
Mon script actuel (j'ai juste fait les minuscules...):

#!/bin/bash

echo "" > fichier
sed -i '/^$/d' fichier
until [ "$choix" = "0" ]; do
read -p 'Texte : ' texte
echo -e "$texte" >> fichier

sed -i 's/a)\\|/ᾂ/g;s/h)\\|/ᾒ/g;s/w)\\|/ᾢ/g' fichier
sed -i 's/a(\\|/ᾃ/g;s/h(\\|/ᾓ/g;s/w(\\|/ᾣ/g' fichier
sed -i 's/a)\/|/ᾄ/g;s/h)\/|/ᾔ/g;s/w)\/|/ᾤ/g' fichier
sed -i 's/a(\/|/ᾅ/g;s/h(\/|/ᾕ/g;s/w(\/|/ᾥ/g' fichier
sed -i 's/a)=|/ᾆ/g;s/h)=|/ᾖ/g;s/w)=|/ᾦ/g' fichier
sed -i 's/a(=|/ᾇ/g;s/h(=|/ᾗ/g;s/w(=|/ᾧ/g' fichier
sed -i 's/a)\\/ἂ/g;s/e)\\/ἒ/g;s/h)\\/ἢ/g;s/i)\\/ἲ/g;s/o)\\/ὂ/g;s/u)\\/ὒ/g;s/w)\\/ὢ/g' fichier
sed -i 's/a(\\/ἃ/g;s/e(\\/ἓ/g;s/h(\\/ἣ/g;s/i(\\/ἳ/g;s/o(\\/ὃ/g;s/u(\\/ὓ/g;s/w(\\/ὣ/g' fichier
sed -i 's/a)\//ἄ/g;s/e)\//ἔ/g;s/h)\//ἤ/g;s/i)\//ἴ/g;s/o)\//ὄ/g;s/u)\//ὔ/g;s/w)\//ὤ/g' fichier
sed -i 's/a(\//ἅ/g;s/e(\//ἕ/g;s/h(\//ἥ/g;s/i(\//ἵ/g;s/o(\//ὅ/g;s/u(\//ὕ/g;s/w(\//ὥ/g' fichier
sed -i 's/a)|/ᾀ/g;s/h)|/ᾐ/g;s/w)|/ᾠ/g' fichier
sed -i 's/a(|/ᾁ/g;s/h(|/ᾑ/g;s/w(|/ᾡ/g' fichier
sed -i 's/a\\|/ᾲ/g;s/h\\|/ῂ/g;s/w\\|/ῲ/g' fichier
sed -i 's/a\/|/ᾴ/g;s/h\/|/ῄ/g;s/w\/|/ῴ/g' fichier
sed -i 's/a)=/ἆ/g;s/h)=/ἦ/g;s/i)=/ἶ/g;s/u)=/ὖ/g;s/w)=/ὦ/g' fichier
sed -i 's/a(=/ἇ/g;s/h(=/ἧ/g;s/i(=/ἷ/g;s/u(=/ὗ/g;s/w(=/ὧ/g' fichier
sed -i 's/i+\\/ῒ/g;s/u+\\/ῢ/g' fichier
sed -i 's/i+\//ΐ/g;s/u+\//ΰ/g' fichier
sed -i 's/i+=/ῗ/g;s/u+=/ῧ/g' fichier
sed -i 's/a=|/ᾷ/g;s/h=|/ῇ/g;s/w=|/ῷ/g' fichier
sed -i 's/a)/ἀ/g;s/e)/ἐ/g;s/h)/ἠ/g;s/i)/ἰ/g;s/o)/ὀ/g;s/u)/ὐ/g;s/w)/ὠ/g;s/r)/ῤ/g' fichier
sed -i 's/a(/ἁ/g;s/e(/ἑ/g;s/h(/ἡ/g;s/i(/ἱ/g;s/o(/ὁ/g;s/u(/ὑ/g;s/w(/ὡ/g;s/r(/ῥ/g' fichier
sed -i 's/a\\/ὰ/g;s/e\\/ὲ/g;s/h\\/ὴ/g;s/i\\/ὶ/g;s/o\\/ὸ/g;s/u\\/ὺ/g;s/w\\/ὼ/g' fichier
sed -i 's/a\//ά/g;s/e\//έ/g;s/h\//ή/g;s/i\//ί/g;s/o\//ό/g;s/u\//ύ/g;s/w\//ώ/g' fichier
sed -i 's/a|/ᾳ/g;s/h|/ῃ/g;s/w|/ῳ/g' fichier
sed -i 's/a=/ᾶ/g;s/h=/ῆ/g;s/i=/ῖ/g;s/u=/ῦ/g;s/w=/ῶ/g' fichier
sed -i 's/a-/ᾰ/g;s/i-/ῐ/g;s/u-/ῠ/g' fichier
sed -i 's/i+/ϊ/g;s/u+/ϋ/g' fichier
sed -i 's/a_/ᾱ/g;s/i_/ῑ/g;s/u_/ῡ/g' fichier
sed -i 's/a/α/g;s/b/β/g;s/g/γ/g;s/d/δ/g;s/e/ε/g;s/z/ζ/g;s/h/η/g;s/q/θ/g;s/i/ι/g;s/k/κ/g;s/l/λ/g;s/m/μ/g;s/n/ν/g;s/c/ξ/g;s/o/ο/g;s/p/π/g;s/r/ρ/g;s/s/σ/g;s/j/ς/g;s/t/τ/g;s/u/υ/g;s/f/φ/g;s/x/χ/g;s/y/ψ/g;s/w/ω/g;s/A/Α/g;s/B/Β/g;s/G/Γ/g;s/D/Δ/g;s/E/Ε/g;s/Z/Ζ/g;s/H/Η/g;s/Q/Θ/g;s/I/Ι/g;s/K/Κ/g;s/L/Λ/g;s/M/Μ/g;s/N/Ν/g;s/C/Ξ/g;s/S/Ο/g;s/P/Π/g;s/R/Ρ/g;s/S/Σ/g;s/T/Τ/g;s/U/Υ/g;s/F/Φ/g;s/X/Χ/g;s/Y/Ψ/g;s/W/Ω/g' fichier
read -p 'Nouveau texte ? : ' choix
done
sed -i 's/[(,),/,\,=,|,+,_]//g' fichier
sed -i 's/-//g' fichier
echo "========================"
cat fichier
echo "========================"

Je voudrais si possible adopter la syntaxe suivante lors de la saisie:

bla bla [blu blu]

où bla bla est en français et blu blu la partie à interpréter par le script.
Je cherche donc à ce que le script n'interprète que les éléments compris entre [ et  ]. Précision, il peut y avoir plusieurs parties [blu blu] dans le fichier.
Je souhaite conserver tous les [ et ].

Merci pour votre aide,
Cordialement

Dernière modification par Le Goss (Le 16/08/2014, à 09:48)


Si je pose une question sur le forum, ce n'est pas par paresse ou pour faire faire "mes devoirs"; c'est par ignorance: j'ai 51 berges. Et, par principe, je préfère être traité d'ignare que de fainéant.
Samsung i7-3630QM CPU @ 2.40GHz × 8 - 64 bits - RAM 7,7 Gio - DD 976 Go - Bodhi 6.0.0 Ubuntu 20.04
Allergique au wysiwyg; traitement à vie: Lilypond - LaTeX - txt2tags

Hors ligne

#2 Le 16/08/2014, à 04:47

nesthib

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Je trouve ta façon de faire plutôt crado, tu vas lire ton fichier entièrement de multiples fois pour faire toutes ces substitutions. Ça n'est vraiment pas efficace, sans parler du côté peu évolutif de la liste de substitutions…

Je te propose le script python suivant :

#!/usr/bin/python
# coding: utf-8

import re, sys

# dictionnaire des termes à remplacer
substitutions = {}
with open('/tmp/dictionnaire') as f:
    for line in f.readlines():
        a, b = line.decode('utf-8').split(' ', 1)
        substitutions[a] = b.strip()

# expression rationelle pour extraire les motifs entre crochets
get_bracket = re.compile('\[([^][]+)\]')

# expression rationelle pour extraire les termes à remplacer
get_letters = re.compile('\w[^\w\s]*')

# fonction de substitution des termes vers les lettres grecs
def togreek(pattern):
    return get_letters.sub(lambda m: substitutions[m.group()] if m.group() in substitutions else m.group(), pattern)

# on lit le fichier d'entrée ligne à ligne et on effectue les substitutions vers un nouveau fichier
with (open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin) as f_in, (open(sys.argv[2], 'w') if len(sys.argv) > 2 else sys.stdout) as f_out:
    for line in f_in.xreadlines():
        # on détecte les motifs entre crochets et on remplace par les lettres grecques
        transcribed = get_bracket.sub(lambda m: '[%s]' % togreek(m.group(1)), line.decode('utf-8'))
        # print(transcribed[:-1])
        f_out.write(transcribed.encode('utf-8'))

Tu auras besoin d'un fichier « dictionnaire » (à redéfinir dans le script, par défaut /tmp/dictionnaire), comportant la liste des substitutions à effectuer au format suivant :

a α
b β
g γ
…
a) ἀ
a)\| ᾂ

En résumé, le script lit le fichier d'entrée, recherche les motifs entre […] et effectue la substitution sur chaque groupe de caractère correspondant à une lettre éventuellement suivie d'autres symboles (ex. « a)\| »).

Le script se lance de la façon suivante :

./script.py "fichier_entrée" "fichier_sortie"

Le fichier d'entrée est facultatif. S'il est omis, le script lira le texte à substituer sur l'entrée standard.
Le fichier de sortie est facultatif. S'il est omis, le script affichera le texte sur la sortie standard (il n'est toutefois pas possible de spécifier de fichier de sortie s'il n'y a pas de fichier d'entrée).

Autre exemple :

$ ./script.py <<EOF
ceci est un test [ceci est un test]
avec parfois plusieurs groupes [avec parfois plusieurs groupes] à traiter par ligne [a)\| traiter par ligne]
EOF
ceci est un test [ξεξi εσt υn τεστ]
avec parfois plusieurs groupes [αvεc παρφοιs πλυσιευρs γρουπεσ] à traiter par ligne [ᾂ τραιτεr παr λιγνε]

Il y a bien entendu de nombreuses améliorations à apporter mais ça devrait te faire une bonne base de travail wink


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#3 Le 16/08/2014, à 08:48

Le Goss

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

nesthib a écrit :

Je trouve ta façon de faire plutôt crado

Pourtant, je me suis appliqué ! merci quand-même pour ta franchise big_smile.

nesthib a écrit :

Ça n'est vraiment pas efficace

Ce n'est pas la première fois qu'on m'en fait la remarque; alors je pose la question: est-ce que tu parles de la rapidité de l'exécution du script ou de l'esthétique de la chose? ... même pas eu le temps de déclencher mon chrono moi.

nesthib a écrit :

sans parler du côté peu évolutif de la liste de substitutions

En même temps, le grec ancien ne créera pas beaucoup de nouvelles lettres à l'avenir lol.
En revanche, ça peut certainement s'appliquer à un autre de mes scripts que j'ai écris, lui, vraiment à l'arrache

nesthib a écrit :

Je te propose le script python suivant

Moi qui avais déjà un peu de mal avec bash...
La plupart de mes scripts utilisent sed en TRES-GRANDE quantité pour faire des remplacements, et peut-être pas toujours de façon judicieuse. C'est peut-être ce à quoi tu penses plus haut.
Avant de me pencher sur bash, je m'étais intéressé à python. J'avais à l'époque trouvé l'apprentissage quelque peu rugueux.
Mais bon... si j'étais convaincu et surtout si je comprenais sa raison d'être en fonction de mes besoins, je retenterais l'expérience.

nesthib a écrit :

Il y a bien entendu de nombreuses améliorations à apporter mais ça devrait te faire une bonne base de travail

Merci pour toutes les explications jointes au codes. Je vais essayer de décortiquer tout ça.
Ce n'est pas que j'ai une mauvaise volonté, mais c'est quand-même pas gagné. hmm


Si je pose une question sur le forum, ce n'est pas par paresse ou pour faire faire "mes devoirs"; c'est par ignorance: j'ai 51 berges. Et, par principe, je préfère être traité d'ignare que de fainéant.
Samsung i7-3630QM CPU @ 2.40GHz × 8 - 64 bits - RAM 7,7 Gio - DD 976 Go - Bodhi 6.0.0 Ubuntu 20.04
Allergique au wysiwyg; traitement à vie: Lilypond - LaTeX - txt2tags

Hors ligne

#4 Le 16/08/2014, à 09:48

Le Goss

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Les premiers essais sont concluants. Et c'est quand-même beaucoup plus propre.
Maintenant, faut que je pige comment ça fonctionne pour adapter à mes autres besoins.
Merci à toi.
Sujet Résolu.


Si je pose une question sur le forum, ce n'est pas par paresse ou pour faire faire "mes devoirs"; c'est par ignorance: j'ai 51 berges. Et, par principe, je préfère être traité d'ignare que de fainéant.
Samsung i7-3630QM CPU @ 2.40GHz × 8 - 64 bits - RAM 7,7 Gio - DD 976 Go - Bodhi 6.0.0 Ubuntu 20.04
Allergique au wysiwyg; traitement à vie: Lilypond - LaTeX - txt2tags

Hors ligne

#5 Le 16/08/2014, à 15:47

nesthib

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Ce qui n'est pas propre c'est que tes commandes sed vont lire à chaque fois tout le fichier. Imagine que tu demandes à un ami de relire ton texte, mais tu lui donnes pour instruction de s'occuper uniquement des « a » à la première lecture, puis des « b » à la seconde, etc. À l'inverse, ma façon de faire lit le fichier ligne à ligne, extrait les motifs entre crochets et remplace le texte caractère par caractère, ce qui fait que le texte n'est lu qu'une seule fois.

Je ne doute pas que le script fonctionne, ni qu'il soit relativement rapide, mais je voulais te faire remarque ce que je considère comme une mauvaise pratique. Si tu dois travailler un jour sur un texte de la taille d'un livre tu vas vite sentir la différence wink
Pour le côté évolutif, je me doute qu'en l'état il ne va pas y avoir de nouvelles lettres, mais tu peux vouloir adapter le script à d'autre besoins.

Voilà, c'était juste une suggestion en espérant que tu prennes goût à python, car ça permet quand même de faire des choses bien sympa et évoluées. N'hésite pas à demander si tu as besoin d'explications ou d'aide pour modifier quelque chose. Précise tes autres besoins. smile


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#6 Le 16/08/2014, à 16:11

Le Goss

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Merci pour ces éclaircissements.
Aurais-tu sous la main quelques liens qui me permettraient de connaître l'étendue de ce qu'on peut faire avec python?
Je tombe souvent sur des codes; mais ils sont incompréhensibles (pour moi), et je ne sais pas à quoi ils servent au juste.
Avant de m'arrêter sur la syntaxe, j'aimerais savoir en quoi python me serait utile à commencer par le traitement de fichier.
@+


Si je pose une question sur le forum, ce n'est pas par paresse ou pour faire faire "mes devoirs"; c'est par ignorance: j'ai 51 berges. Et, par principe, je préfère être traité d'ignare que de fainéant.
Samsung i7-3630QM CPU @ 2.40GHz × 8 - 64 bits - RAM 7,7 Gio - DD 976 Go - Bodhi 6.0.0 Ubuntu 20.04
Allergique au wysiwyg; traitement à vie: Lilypond - LaTeX - txt2tags

Hors ligne

#7 Le 16/08/2014, à 16:32

nesthib

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Houla, vaste programme… python est un langage de programmation avec d'innombrables bibliothèques, je pense qu'à peu près tout ce que tu peux faire avec d'autres langages tu peux le faire avec python, donc je ne m'inquiéterais pas pour ça wink
Un classique pour apprendre python est le livre Apprendre à programmer avec Python. Si c'est la première fois que tu essaies python tu devrais sûrement commencer avec python 3 (il y a eu pas mal d'évolution de langage entre la version 2 et 3).

Pourquoi ne donnerais-tu pas une liste des problèmes que tu cherches à résoudre ? J'essaierai de te donner des pistes pour trouver une solution.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#8 Le 16/08/2014, à 17:24

Le Goss

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

nesthib a écrit :

Pourquoi ne donnerais-tu pas une liste des problèmes que tu cherches à résoudre ?

A l'image de ce sujet, je cherche à créer, au fur et à mesure de mes besoins, des scripts servant à traiter des fichiers texte, en leur appliquant diverses modification: remplacements, suppressions etc. D'où mon utilisation intensive de sed entre autres.
Les fichiers (sources ou cibles) peuvent être au format latex, lilypond, html, xml... et, selon le cas, en passant par txt2tags.

nesthib a écrit :

J'essaierai de te donner des pistes pour trouver une solution.

Merci beaucoup!
J'ai déjà de quoi potasser, et la tache m'apparaît ardue.
Je ne manquerai pas de revenir sur le forum en cas de besoin.


Si je pose une question sur le forum, ce n'est pas par paresse ou pour faire faire "mes devoirs"; c'est par ignorance: j'ai 51 berges. Et, par principe, je préfère être traité d'ignare que de fainéant.
Samsung i7-3630QM CPU @ 2.40GHz × 8 - 64 bits - RAM 7,7 Gio - DD 976 Go - Bodhi 6.0.0 Ubuntu 20.04
Allergique au wysiwyg; traitement à vie: Lilypond - LaTeX - txt2tags

Hors ligne

#9 Le 16/08/2014, à 18:12

nesthib

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Je vois exactement le type de besoins. J'ai déjà eu à faire des choses similaires sur des documents de plusieurs centaines de pages. Ex. changer les niveaux de titre (incrémenter, décrémenter) dans un document LaTeX, mettre à jour des citations, etc. Bien que j'aie utilisé des scripts bash (+ sed/awk/grep/…), j'utiliserais python sans hésitation si c'était à refaire.

Pour tous les documents qui utilisent des balises, l'idéal est de travailler avec un parseur, un programme qui va « comprendre » la grammaire du langage (ex. LaTeX, html) et te permettre d'y apporter des modifications. C'est la meilleure solution théorique, mais en pratique ça peut être compliqué à mettre en œuvre. Une astuce qui fonctionne dans la plupart des cas est de détecter les balises avec une expression rationnelle. Par exemple :

Détecter une balise « \textit[…] » en LaTeX pour changer le contenu (et, par exemple, le mettre en majuscule). L'expression rationnelle (python) serait :

'\\textit\[([^][]+)\]'

se qui se traduit par → détecter une séquence qui commence par « \textit[ » (on échappe le \ avec un double \\ et le [ avec \[), suivi d'une suite de caractères d'au moins 1 caractère (+) qui soit n'importe quoi, sauf des crochets « [^][] », (la syntaxe pour n'importe quelle voyelle serait par exemple [aeiouy], et pour tout sauf des voyelles : [^aeiouy], donc ici tout sauf des crochets « ][ »). Enfin on demande que la chaîne soit suivie d'un ] (\]) et que la partie conservée soit seulement ce qui est entre les […] (pour cela on utilise les parenthèses).

Avec cette astuce tu peux travailler avec la plupart des langages balisés pour y faire des substitutions simples. Attention cependant, si tu dois faire des tâches plus avancées, ou que tu as des balises imbriquées tu devras alors utiliser un parseur.

Bon courage et n'hésite pas à ouvrir de nouveaux fils de disussion wink


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#10 Le 16/08/2014, à 18:19

melixgaro

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

salut,

c'est plutôt

\textit{}

non ?


Linux depuis ~2007. Xubuntu seulement.

Hors ligne

#11 Le 16/08/2014, à 18:36

nesthib

Re : [Résolu] Bash: sed n'interpréter que certaines parties du fichier

Oui pardon, enfin ça ne change pas grand chose au problème, il suffit de remplacer « \[ » par « { » wink


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne