Extraire plusieurs sous-chaine dans une ligne

Résolu/Fermé
Kai - 23 sept. 2010 à 18:40
 Kai - 24 sept. 2010 à 11:31
Bonjour,

Je dois récupérer toute les chaines comprise entre _(" et ") -gettext pour ceux qui connaissent.
J'utilise actuellement sed, j'ai essayé avec grep également mais rien à faire. Tous les exemples que j'ai trouvé fonctionnent si il y a une occurrence du motif PAR lignes...

***Voici un fichier d'exemple (fichier.txt):
echo("Voici une "._("phrase sans erreur"). " et "._("sans suite").". "._("Ceci est un exemple") );

A chaque fois que je tente quelque chose, SED me récupère que la dernière occurence...
***commande :
$> sed -e 's/.*_("\(.*\)").*/\1/' fichier.txt
Résultat : Ceci est un exemple

J'ai également essayé de mettre ma commande dans une boucle FOR mais il me décompose ma phrase en :
Ceci
est
un
exemple



Si vous avez des idées : je suis preneur ! Et merci d'avance!
A voir également:

7 réponses

jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
23 sept. 2010 à 19:03
Salut;

$ echo $A
echo("Voici une "._("phrase sans erreur"). " et "._("sans suite").". "._("Ceci est un exemple") );

$ echo $A | egrep -o '_\("[^"]*"\)' | sed 's/_("\|")//g'
phrase sans erreur
sans suite
Ceci est un exemple

$

;-))
3
Malekal_morte- Messages postés 180304 Date d'inscription mercredi 17 mai 2006 Statut Modérateur, Contributeur sécurité Dernière intervention 15 décembre 2020 24 628
Modifié par Malekal_morte- le 23/09/2010 à 18:49
Salut,

tu peux le faire avec grep, si j'ai bien compris ce que tu voulais :/

malekalmorte@neptune:/tmp$ cat pouet
echo("Voici une "._("phrase sans erreur"). " et "._("sans suite").". "._("Ceci est un exemple") );
malekalmorte@neptune:/tmp$ cat pouet|grep -Eoi "\(\"([a-z]| )+\"\)"
("phrase sans erreur")
("sans suite")
("Ceci est un exemple")


Après faut virer les (" et "), si tu n'en veux pas.

Les hommes réunissent tous les erreurs de leur vie et créent un monstre qu'il appelle destin.
1
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
Modifié par lami20j le 23/09/2010 à 19:16
Salut,

On peut faire grep motif fichier , cat n'est pas obligatoire
Sinon, on peut aussi simplifier la regex ;-)

:~$ cat pouet|grep -Eoi "\(\"([a-z]| )+\"\)"                      
("phrase sans erreur")   
("sans suite")   
("Ceci est un exemple")   
:~$ grep -Eoi "\(\"([a-z]| )+\"\)" pouet   
("phrase sans erreur")   
("sans suite")   
("Ceci est un exemple")   
:~$ grep -Eoi "\(\"(\w| )+\"\)" pouet   
("phrase sans erreur")   
("sans suite")   
("Ceci est un exemple")   
:~$ grep -Eoi '\("([^"]| )+"\)' pouet   
("phrase sans erreur")   
("sans suite")   
("Ceci est un exemple")
0
Malekal_morte- Messages postés 180304 Date d'inscription mercredi 17 mai 2006 Statut Modérateur, Contributeur sécurité Dernière intervention 15 décembre 2020 24 628
Modifié par Malekal_morte- le 23/09/2010 à 22:03
On peut faire grep motif fichier , cat n'est pas obligatoire

Je sais bien mais c'est une sale habitude, pis j'aime les pipes :/
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
Modifié par lami20j le 23/09/2010 à 19:30
Re,

Sinon avec les tests avant/arrière

~$ perl -ne 'while(/(?<=\(")([^"]+)(?="\))/g){print "$1\n"}' pouet 
phrase sans erreur 
sans suite 
Ceci est un exemple


GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
106485010510997108
1
si grep est compilé avec support pcre :
grep -Po '(?<=")[^"]+(?=")' fichier.txt
0

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

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
23 sept. 2010 à 19:56
Re,

Oui, bien sûr ;-)
Toutefois il faut tenir compte (dans son exemple) que le teste avant c'est sur (" et le teste arrière sur ") ce qui donne
lami20j@debian-acer:~$ grep -Po '(?<=")[^"]+(?=")' pouet 
Voici une 
._(
phrase sans erreur
). 
 et 
._(
sans suite
).
. 
._(
Ceci est un exemple
lami20j@debian-acer:~$ grep -Po '(?<=\(")[^"]+(?="\))' pouet 
phrase sans erreur
sans suite
Ceci est un exemple

0
Exact, je n'avais pas fait attention.

Une autre syntaxe en perl, pour le même résultat :
perl -nle 'print for /(?<=\(")([^"]+)(?="\))/g' fichier.txt
0
Bonjour,

Merci à tous car la plupart de vos solutions fonctionnent dans mon script shell!!

A lami20j : peut tu m'expliquer le détail de ta reg expr stp?
(?<=\(")[^"]+(?="\))

A jipicy : Pareillement. Avec egrep tu trouve la ligne et avec sed les chaines exactement comprise entre _(" et ") ??
egrep -o '_\("[^"]*"\)' | sed 's/_("\|")//g'


Merci encore et bonne journée!
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 895
24 sept. 2010 à 09:35
Re-

egrep -o '_\("[^"]*"\)' ne récupère que chaque expression commençant par _(" et tout ce qui suit jusqu'au prochain ".

sed 's/_("\|")//g' supprime le superflu, à savoir les _(" du début et les ") de fin...
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
24 sept. 2010 à 10:02
Salut,

(?<=\(")[^"]+(?="\))

(?<=\(")

Il s'agit d'un test arrière (?<=MOTIF)
Le MOTIF dans notre cas c'est une parenthèse ouvrante suivie par guillemets. \("
On met un backslash avant la parenthèse puisque dans les regex les parenthèses ont le rôle de capture.


(?="\))

Il s'agit d'un test avant (?=MOTIF)
Le MOTIF dans notre cas c'est guillemets suivie d'une parenthèse fermante. "\)
On met un backslash avant la parenthèse puisque dans les regex les parenthèses ont le rôle de capture.

[^"]+

[^"] - c'est une classe de caractères qui permet de reconnaître n'importe quel caractère sauf les guillemets

+ - c'est un quantificateur qui veut dire une fois ou n'importe combien des fois.

Avec la regex on regarde en arrière pour voir si on a une parenthèse ouvrante suivi de guillemets et devant pour voir s'il y a guillemets suivis d'une parenthèse fermante.
Les tests avant ne consomment pas de textes. Ils trouvent juste une position avant ou arrière.

Dans un langage plus accessible pour nous les humains c'est
Cherche n'importe quelle chaîne de caractères qui ne contienne pas des guillemets et qui se trouve entre (" et ")
0
Ok, merci !

Le truc c'est que j'ai besoin de chaque chaine trouvée pour vérifier si elles sont présentes dans un autre fichier...
Et quand je veux parcourir mon résultat , voila ce que ca donne:

$> for chaine in 'echo 'echo("Voici une "._("phrase sans erreur"). " et "._("sans suite").". "._("Ceci est un exemple") );' | egrep -o '_\("[^"]*"\)' | sed 's/_("\|")//g''; do echo "chaine :"$chaine; done
chaine :phrase
chaine :sans
chaine :erreur
chaine :sans
chaine :suite
chaine :Ceci
chaine :est
chaine :un
chaine :exemple



Comment dire au FOR de ne pas casser mes lignes pour récupérer :
chaine :phrase sans erreur
chaine :sans suite
chaine :Ceci est un exemple


???
0
Malekal_morte- Messages postés 180304 Date d'inscription mercredi 17 mai 2006 Statut Modérateur, Contributeur sécurité Dernière intervention 15 décembre 2020 24 628
24 sept. 2010 à 10:10
Fais avec while.
C'est mieux pour lire ligne par ligne.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 567
24 sept. 2010 à 10:23
Re,

Ou avec un tr

$ for chaine in $(echo '("Voici une "._("phrase sans erreur"). " et "._("sans suite").". "._("Ceci est un exemple") )'| egrep -o '_\("[^"]*"\)' | sed 's/_("\|")//g'|tr ' ' _); do echo "chaine : ${chaine//_/ }"; done
chaine : phrase sans erreur
chaine : sans suite
chaine : Ceci est un exemple
0