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 04/12/2014, à 14:16

L'Africain

(Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Bonjour,
Voilà j'ai un très long texte dont chaque ligne commence par $$$ et un mot suivit d'une référence, exemple :

$$$Genesis 1,1 Au commencement Dieu créa le ciel et la terre...

Je dois mettre ce qui suit la référence à la ligne pour chaque verset, comme ceci :

$$$Genesis 1,1
Au commencement Dieu créa le ciel et la terre...
$$$Genesis 1,2
Dieu dit...

Quelqu'un aurait une idée pour scripter ça sachant que le mot peut-être différent de Genesis et les réferences peuvent monter à deux chiffres comme 51,22.
Merci pour votre aide.

Dernière modification par L'Africain (Le 04/12/2014, à 17:18)


Ubuntu-Unity 18.04 LDLC (clevo) X/Lubuntu-Mate
"Donne à celui qui te demande…" Mt 5,42

Hors ligne

#2 Le 04/12/2014, à 15:28

pingouinux

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Bonjour,

sed -r 's/^(\$\$\$[^ ]+ +[0-9]+,[0-9]+) +/\1\n/' fichier_d_origine >fichier_modifié

ou, pour modifier directement le fichier d'origine

sed -ri 's/^(\$\$\$[^ ]+ +[0-9]+,[0-9]+) +/\1\n/' fichier_d_origine

Hors ligne

#3 Le 04/12/2014, à 15:34

credenhill

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

hello

$ sed -r '/^\${3}/s/[0-9]*,[0-9]* /&\n/'  fichier

Hors ligne

#4 Le 04/12/2014, à 17:14

L'Africain

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Je vous remercie, ça marche, j'avais juste un espace en début de ligne que j'ai supprimé comme ça:

sed 's/^ *//g' sortie_final2.txt >sortie_final3.txt

Vous pouvez juste m'expliquer les lignes?
Je comprends : $(3) ça veut dire qu'il y a trois fois ce caractère, aussi ça je comprends  [0-9]*,[0-9]* chiffre compris de 0 à 9 séparé par une virgule. mais le mot entre les $ et les chiffres c'est quoi qui l'identifie?


Ubuntu-Unity 18.04 LDLC (clevo) X/Lubuntu-Mate
"Donne à celui qui te demande…" Mt 5,42

Hors ligne

#5 Le 04/12/2014, à 17:32

credenhill

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

sur les lignes qui commencent par $$$, on remplace nombre,nombre>espace> par nombre,nombre\n
sans s'occuper du mot après $$$

Hors ligne

#6 Le 04/12/2014, à 18:13

αjet

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Pour le probleme d'espace l'expression singuliere (regular expression en anglais) de pingouinux est la meilleure.
Voici un outil sympa pour visualiser le comportement d'une expression:
Visualiser une regex

Quelques notes sur tes questions
1. C'est \${3} qui capture 3 signes $ consecutifs. Le caractere \ d'echapement est necessaire car le signe $ a une signification particuliere: c'est le symbole de fin de ligne
2. [0-9] est une classe de caracteres, ce qui signifie que tout caractere entre 0 et 9 seront valides, * veut dire 0 ou plus, + veut dire 1 ou plus
3. Pour ce qui est entre les $ et les nombres:
a. [^ ]+ capture au moins un caractere qui ne soit pas le caractere espace. Dans une classe de caractere, ^ est une negation (i.e. tous les caracteres sauf ceux specifies dans la classe sont captures).
b. " +" (sans les quotes) capture 1 ou plusieurs espaces.
c. Donc  [^ ]+ + capture une serie de caracteres qui ne sont pas des espaces suivis par au moins 1 espace. C'est cette partie la qui capture "Genesis " dans ton exemple. Note que si les titres peuvent contenir plus d'un mot, cette partie de l'expression ne sera pas valide. S'il est possible que des titres aient plus d'un mot, alors cette partie de l'expression aurait pu etre ecrit ".*?" (sans les quotes). Le point capture n'importe quel caractere, *? est un "lazy quantifier" qui va capturer aussi peu de caractere que necessaire pour que l'expression soit valide.

Si tu veux en savoir plus, cherche regular expression, expression singuliere (traduction correcte) ou expression reguliere (traduction usuelle).
Si tu lis l'anglais, je peux te recommander ce site: http://www.regular-expressions.info/quickstart.html

Dernière modification par αjet (Le 04/12/2014, à 18:15)


αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr

Hors ligne

#7 Le 05/12/2014, à 09:27

L'Africain

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Merci ajex pour toutes ces explications. C'est très utile. Je vais aller lire les liens. Mais en gros j'ai compris, maintenant pour l'appliquer...
Bon si je peux... j'ai encore une question. Si vous pensez que c'est mieux d'ouvrir un nouveau post, je peux aussi, mais ça reste dans le même sujet:
J'ai des livres manquants dans ce fichier texte que l'on vient de créer pour bibletime (vous avez deviner qu'il s'agit de la Bible??).
Or les fichiers textes des livres manquants se présentes ainsi :

Tobit # (nom du livre)
1 # (indique le chapitre, est suivi d'un retour à la ligne)
1  Histoire de Tobit, fils de Tobiel, ...
2  Aux jours de Salmanasar, ...
3  Moi, Tobit... 4  Dans ma jeunesse....
...
64...

2 # Indique un nouveau chapitre
1 ...
2...

Donc chaque verset est numéroté et quand le chapitre est fini la numérotation reprend à 1, 2.
Comment faire pour changer chaque chiffre correspondant au verset par :

$$$nom _du_livre 1,(numéro de chapitre)1(numéro de verset)
Histoire de Tobit, fils de Tobiel, ...
$$$nom _du_livre 1,2
Aux jours de Salmanasar, ..

Le script doit voir que la numérotation reprend à 1 et passer au chiffre du chapitre suivant. j'espère que mes explication ne sont pas trop confuse...
On m'a envoyé un script perl qui est chargé de faire une chose similaire (sauf qu'il ne met pas le verset à la ligne mais ça maintenant je sais le faire)  que je n'arrive pas à utiliser, en voici le contenu :

#!/usr/bin/perl

$entree = $ARGV[0];
$sortie = $entree."trait";

# Section 1 : insertion de sauts de lignes dans le fichier unicode
#-------------------------------------------------------------------

print "Ouverture de $entree\n";

  open(FICLOC, $entree);

print "Lecture de $entree\n";

    $bible = <FICLOC>;
    chop($bible);
print "Scission des versets\n";

$bible =~ s/(\d\d?\s)/\n$1/g;

print "Ouverture du fichier de sortie\n";

  
  open(FICOUT, ">$sortie");

print "Ecriture des versets\n";
print FICOUT "$bible";

__END__

# Section 2 : Recherche des numéros de chapitre, et insertion du nom de livre
# ----------------------------------------------------------------------------
print "Ouverture de $entree\n";

  open(FICLOC, $entree);
  open(FICOUT, ">$sortie");

print "Lecture de $entree\n";

while ($verset = <FICLOC>) {
    chop($verset);
    if ($verset =~ /^<(.*)>$/) {
        print "Traitement du livre $1\n";
#         print FICOUT "$verset\n";
#         $verset =~ s/[<>]//g;
        $livre = $1;
        $chapitre = 0;
        next;
        }
    if ($verset =~ /^(\d\d?)§(\d\d?)$/) {
        $chapitre = $1;
        $vers = $2;
        $premier = 1;
        next;
        }
    if ($verset =~ /^(\d\d?)$/) {
    	$vers = $1 ;
    	$premier = 1;
    	next;
    	}
# on arrive ici s'il n'y a pas de chiffre...
    if ($premier == 1) {
    	print FICOUT "\n$livre $chapitre:$vers $verset";
    	$premier = 0;
        } else {
        print FICOUT " $verset";
        }
    }

On est pas obligé d'utiliser ce script on peut repartir de zéro. C'est ce qui vous semble le plus simple.
Merci d'avance !

Dernière modification par L'Africain (Le 05/12/2014, à 10:05)


Ubuntu-Unity 18.04 LDLC (clevo) X/Lubuntu-Mate
"Donne à celui qui te demande…" Mt 5,42

Hors ligne

#8 Le 05/12/2014, à 14:01

αjet

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Je pense que ce serait mieux que tu reposte dans un nouveau fil ce serait mieux (1 pb par fil de discussion). Suggestion: copie le texte et mets un lien ici vers le nouveau fil.

En supposant que la ligne de no de chapitre ne comprenne que ce no - eventuellement suivit d'espaces, je propose ce pseudo code perl - pas teste, peut etre des erreurs de syntaxe a corriger

# Par la suite, je suppose que le titre est dans la variable $book_title
while ($line = <FICLOC>)
# Detection de chapitre
  if ($line =~ '/^(\d+)\s*$/') {
     $n_chapter = $1;
  }

## Detection de versets
  if ($line =~ '/^(\d+)\s+(.+)$/') {
    $n_verse = $1;
    $text_verse = $2;
    $formatted_text = "\$\$\$$book_title $n_chapter,$n_verse\n$text_verse";
   # Ecriture de cette ligne dans le fichier texte
    print FICOUT "$formatted_text\n";
  }
}

αjet: ça se prononce alfajet, bordel ! | GMT+1 | Viens poueter avec moi, bordel ! | Mes photos | Shaarli | Fluidbuntu-fr

Hors ligne

#9 Le 05/12/2014, à 18:29

L'Africain

Re : (Résolu) À la ligne (avec sed) dans une partie précise d'un texte

Ok j'ouvre un nouveau post ici. J'y ai mis les retours du terminal.


Ubuntu-Unity 18.04 LDLC (clevo) X/Lubuntu-Mate
"Donne à celui qui te demande…" Mt 5,42

Hors ligne