Script awk: comment fusionner des lignes?
Résolu
awkgirl
-
Florent -
Florent -
Bonjour,
je dispose d'un corpus anglais et français proposant des lignes (src), soit source, en alternance avec des lignes (trg), soit cible. Le problème est que parfois 2 (ou plus) phrases (src) se suivent pour une seule correspondance (trg), ou, à l'inverse: 2 (ou plus) phrases (trg) se suivent pour une seule phrase (src)
Exemple:
25 (src)="s8.1"> If the spin box defines numerical values , you can
also define a measurement unit , e.g. , 1 cm or 5 mm , 12 pt or 2 " .
26 (trg)="s8.1"> Lorsque vous saisissez une valeur numérique , vous
pouvez aussi spécifier une unité de mesure , par ex .
27 (trg)="s8.2"> 1 cm , 5 mm , 12 pt ou 2 " ( pour 2 pouces ) .
28 (src)="s9.1"> Convert
29 (trg)="s9.1"> Convertir.
Je souhaite donc regrouper les (src) et les (trg) qui se suivent afin de disposer d'un corpus correctement aligné.
Au pire, j'ai un script à renouveler plusieurs fois:
my $file = $ARGV[0];
my $nextline;
open(IN, "< $file") || die "Couldn't open file!";
while(<IN>){
if($_=~m/^\(trg\)="s[0-9]+\.[0-9]+">/){
$nextline=<IN>;
if($nextline=~m/^\(trg\)="s[0-9]+\.[0-9]+">/){
$nextline=~s/\(trg\)="s[0-9]+\.[0-9]+">//;
$_=~s/\n//;
print $_;
print $nextline;
}
else{
print $_;
print $nextline;
}
}
else{
print $_;
}
}
close(IN);
Mais comme je débute, je n'arrive pas à écrire un script awk qui me permettrait de fusionner ces lignes en une seule fois. D'autant que je dois réunir 1000 couples de phrases, et je me vois mal valider mon script 1000 fois au pire des cas... ;-)
Merci beaucoup pour votre aide!
je dispose d'un corpus anglais et français proposant des lignes (src), soit source, en alternance avec des lignes (trg), soit cible. Le problème est que parfois 2 (ou plus) phrases (src) se suivent pour une seule correspondance (trg), ou, à l'inverse: 2 (ou plus) phrases (trg) se suivent pour une seule phrase (src)
Exemple:
25 (src)="s8.1"> If the spin box defines numerical values , you can
also define a measurement unit , e.g. , 1 cm or 5 mm , 12 pt or 2 " .
26 (trg)="s8.1"> Lorsque vous saisissez une valeur numérique , vous
pouvez aussi spécifier une unité de mesure , par ex .
27 (trg)="s8.2"> 1 cm , 5 mm , 12 pt ou 2 " ( pour 2 pouces ) .
28 (src)="s9.1"> Convert
29 (trg)="s9.1"> Convertir.
Je souhaite donc regrouper les (src) et les (trg) qui se suivent afin de disposer d'un corpus correctement aligné.
Au pire, j'ai un script à renouveler plusieurs fois:
my $file = $ARGV[0];
my $nextline;
open(IN, "< $file") || die "Couldn't open file!";
while(<IN>){
if($_=~m/^\(trg\)="s[0-9]+\.[0-9]+">/){
$nextline=<IN>;
if($nextline=~m/^\(trg\)="s[0-9]+\.[0-9]+">/){
$nextline=~s/\(trg\)="s[0-9]+\.[0-9]+">//;
$_=~s/\n//;
print $_;
print $nextline;
}
else{
print $_;
print $nextline;
}
}
else{
print $_;
}
}
close(IN);
Mais comme je débute, je n'arrive pas à écrire un script awk qui me permettrait de fusionner ces lignes en une seule fois. D'autant que je dois réunir 1000 couples de phrases, et je me vois mal valider mon script 1000 fois au pire des cas... ;-)
Merci beaucoup pour votre aide!
A voir également:
- Script awk: comment fusionner des lignes?
- Script vidéo youtube - Guide
- Mas script - Accueil - Windows
- Ghost script - Télécharger - Polices de caractères
- Script cmd - Guide
- Une erreur est survenue dans le script de cette page - Forum Windows 10
11 réponses
Une façon très simple sous awk de grouper des lignes sur une seule ligne est d'utiliser la variable RS (record separator) qui défini la fin d'une ligne.
Normalement égal à \n il suffit de l'ajouter dans l'entête du script pour regrouper les lignes voulues ensemble.
Exemple : sortir les paragraphes d'un fichier html
reste encore à les mettre sur une ligne, ce que les instructions sur les $i de awk permettent par ailleurs.
Voir aussi :
- FS, équivalent pour les champs
- regex1, regex2 qui défini un intervalle de champs ou lignes subissant le même traitement
Normalement égal à \n il suffit de l'ajouter dans l'entête du script pour regrouper les lignes voulues ensemble.
Exemple : sortir les paragraphes d'un fichier html
awk 'BEGIN {RS="</?p>"}{print $0}' page.htm
reste encore à les mettre sur une ligne, ce que les instructions sur les $i de awk permettent par ailleurs.
Voir aussi :
- FS, équivalent pour les champs
- regex1, regex2 qui défini un intervalle de champs ou lignes subissant le même traitement
Salut,
T'es sûre que c'est pas du "Perl" plutôt ton script ?
Tu peux nous afficher davantage de lignes de ton fichier, ou même mieux, le mettre sur Cjoint ;-))
T'es sûre que c'est pas du "Perl" plutôt ton script ?
Tu peux nous afficher davantage de lignes de ton fichier, ou même mieux, le mettre sur Cjoint ;-))
Salut jipicy!
Merci beaucoup de t'être soucié de mon problème!!
Figure-toi que mon prof vient de nous envoyer un mail disant qu'il était lui-même incapable de faire fusionner des lignes en une seule fois. Je crois donc que cette question sera à jamais irrésolue!
En outre, je ne dispose pas du corpus aujourd'hui car il est sur un serveur qui m'est inaccessible ce week-end!
La suite, lundi matin donc!
Un bon week-end à toi!
Merci beaucoup de t'être soucié de mon problème!!
Figure-toi que mon prof vient de nous envoyer un mail disant qu'il était lui-même incapable de faire fusionner des lignes en une seule fois. Je crois donc que cette question sera à jamais irrésolue!
En outre, je ne dispose pas du corpus aujourd'hui car il est sur un serveur qui m'est inaccessible ce week-end!
La suite, lundi matin donc!
Un bon week-end à toi!
Le serveur est down ? ;-))
Salut jispicy!
j'étais tellement occupée ce matin à essayer de résoudre tous ces problèmes épineux que (honte sur moi) je n'ai pas pris le temps de t'en dire plus.
En fait quelqu'un m'a donné unscript qui permet bien de fusionner des lignes:
#! /usr/bin/awk -f
# cleanOO-align.awk
# nettoie
BEGIN {src = 0; trg = 0}
{if ($1 == "====================")#if line starts with +++, copy the whole line. Set src and trg to 0
{
src = 0;
trg = 0;
print $0;
next;
}
}
{if (index($0,"(src)") != 0) #if line starts with (src), check if already exists src, if no, copy whole line, if yes copy just text
{
src++;
if (src > 1)
{
print substr($0, length($1) + 1, length($0))
}
else
{
print $0
};
next;
}
}
{if (index($0, "(trg)") != 0)#if line starts with (trg), check if already exists src, if no, copy whole line, if yes copy just text
{
trg++;
if (trg > 1)
{
print substr($0, length($1) + 1, length($0))
}
else
{
print $0
};
next;
}
}
Le nouveau problème maintenant: il faut supprimer les retours à la ligne engendrés par ce script qui "ne colle pas" les 2èmes phrases aux premières, tu me suis?
En outre j'ajoute qu'on a dû aussi faire des manips à la main pour supprimer des orphelins (des src ou trg seuls), et c'est ça que ne savait pas faire mon prof.
Aurais-tu une petite idée pour supprimer ces retours à la ligne?
Je sais, j'exagère, mais on ne nous a pas appris à écrire de scripts comme celui-là!
La paradoxe est fort! (Molière) ;-)
j'étais tellement occupée ce matin à essayer de résoudre tous ces problèmes épineux que (honte sur moi) je n'ai pas pris le temps de t'en dire plus.
En fait quelqu'un m'a donné unscript qui permet bien de fusionner des lignes:
#! /usr/bin/awk -f
# cleanOO-align.awk
# nettoie
BEGIN {src = 0; trg = 0}
{if ($1 == "====================")#if line starts with +++, copy the whole line. Set src and trg to 0
{
src = 0;
trg = 0;
print $0;
next;
}
}
{if (index($0,"(src)") != 0) #if line starts with (src), check if already exists src, if no, copy whole line, if yes copy just text
{
src++;
if (src > 1)
{
print substr($0, length($1) + 1, length($0))
}
else
{
print $0
};
next;
}
}
{if (index($0, "(trg)") != 0)#if line starts with (trg), check if already exists src, if no, copy whole line, if yes copy just text
{
trg++;
if (trg > 1)
{
print substr($0, length($1) + 1, length($0))
}
else
{
print $0
};
next;
}
}
Le nouveau problème maintenant: il faut supprimer les retours à la ligne engendrés par ce script qui "ne colle pas" les 2èmes phrases aux premières, tu me suis?
En outre j'ajoute qu'on a dû aussi faire des manips à la main pour supprimer des orphelins (des src ou trg seuls), et c'est ça que ne savait pas faire mon prof.
Aurais-tu une petite idée pour supprimer ces retours à la ligne?
Je sais, j'exagère, mais on ne nous a pas appris à écrire de scripts comme celui-là!
La paradoxe est fort! (Molière) ;-)
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Euh...j'ai peut être une solution mais avec "sed" et non "awk", c'est grave ?
Et le fichier, je peux en avoir un plus gros extrait ???
;-)
Et le fichier, je peux en avoir un plus gros extrait ???
;-)
Pas de problème avec sed, de toute façon, au point où j'en suis!
Voici mon fichier: https://www.cjoint.com/?dkoYYFN7R3
Merci infiniment jipicy!!
Voici mon fichier: https://www.cjoint.com/?dkoYYFN7R3
Merci infiniment jipicy!!
[tmpfs]$ sed '/^(trg)/{N;/\n==*/! s/\n//}' OO-enfr-E_ENFR-v3.txt > temp.txt [tmpfs]$ sed '/^(src/{N;/\n(trg)/! s/\n//}' temp.txt > final.txt;-))
Alors là un grand merci et un grand bravo! Ca marche!!
Une dernière petite question: à quoi correspond le N?
Promis, après, je ne t'embête plus (enfin j'espère).
;-)
Une dernière petite question: à quoi correspond le N?
Promis, après, je ne t'embête plus (enfin j'espère).
;-)
Tiens voilà le script dans un fichier et qui traite tout d'un coup, avec commentaires :
Donc à enregistrer dans un fichier (par exemple "script.sed") et à appeler de cette façon :
/^(src)/{ # Si la ligne commencent par N # Ajouter la ligne suivante dans l'espace de travail /\n(trg)/{ # Si le caractère saut de ligne (\n) est suivi de "(trg) P # Afficher la 1ère partie de l'espace de travail (jusqu'au saut de ligne) D # Effacer la 1ère partie de l'espace de travail (jusqu'au saut de ligne) b trg # Et se brancher à l'étiquette "trg" } /\n(src)/!{ # Si le caractère saut de ligne (\n) n'est pas suivi de "(src)" s/\n// # supprimer le caractère saut de ligne (\n) } } :trg # Étiquette /^(trg)/{ # Si la ligne commencent par N # Ajouter la ligne suivante dans l'espace de travail /\n==*/!{ # Si le caractère saut de ligne (\n) n'est pas suivi par des "=" s/\n// # supprimer le caractère saut de ligne (\n) } }
Donc à enregistrer dans un fichier (par exemple "script.sed") et à appeler de cette façon :
sed -f script.sed OO-enfr-E_ENFR-v3.txt > final.txtSi tu as une version de "sed" supérieure à 4.0.5, tu peux éditer directement le fichier original (en faisant une sauvegarde toutefois) de cette façon :
sed -f script.sed -i.BAK OO-enfr-E_ENFR-v3.txt;-))