#1 Le 04/07/2012, à 16:24
- jedineofr
[RESOLU] [sed] Extraire texte contenu entre parenthèses
Bonjour à tous
Je fais un script shell qui doit extraire une suite de chiffre et lettres dans un fichier.
Voici un exemple ou je chercher a obtenir la suite de 18 caractéres (seulement chiffres et lettres) qui est donc A12B34567890CDEFGH
Extrait de fichier_exemple.txt :
File ABZXRW01_GIXRT00_D_NCT03_000_20120704123456.dat ( A12B34567890CDEFGH ) ( ID 069 ) :
J'ai testé avec
sed 's/.*(\(.*\)).*/\1/' fichier_exemple.txt
Mais cela me donne la deuxiéme information entre parenthèses, soit ID 069
Comment faire pour sélectionner que ce qu'il y a dans le premier groupe de parenthèses ?
Merci d'avance
Dernière modification par jedineofr (Le 05/07/2012, à 08:34)
Ubuntu 8.04 LTS -> Ubuntu 8.10 -> Ubuntu 9.04 -> Ubuntu 9.10 -> Ubuntu 10.04 LTS -> Lubuntu 14.04 > Ubuntu 14.04 > Ubuntu 16.04 LTS > Ubuntu 18.04 LTS
Asus ROG G551JW-DM379T (i7 4750HQ, GTX960M, Dd 1 To + SSD 24 Go, Windows 10 + Ubuntu)
Hors ligne
#2 Le 04/07/2012, à 17:19
- ludovic889
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
salut
en grand amateur, j'ai fait ça
sed 's/.*(\(.*\)).*(\(.*\)).*/\1/' truc.txt
qui me renvoie
A12B34567890CDEFGH
mais il doit y avoir beaucoup mieux
Ce n'est pas grave de ne pas avoir l'heure si on a le temps.
Hors ligne
#3 Le 04/07/2012, à 17:49
- sputnick
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
grep -oP '\(\s+\K[[:xdigit:]]+' FILE
A12B34567890CDEF
On ne peut pas mettre d'array dans un string!
https://sputnick.fr/
En ligne
#4 Le 04/07/2012, à 17:51
- sputnick
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
awk -F'[()]' '{print $2}' FILE
A12B34567890CDEFGH
On ne peut pas mettre d'array dans un string!
https://sputnick.fr/
En ligne
#5 Le 04/07/2012, à 23:16
- UbuntOlivier
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
sed 's/.*(\(.*\)).*/\1/' fichier_exemple.txt
Tu y étais presque :
sed 's/[^(]*( \([^)]*\) ).*/\1/' fichier_exemple.txt
Hors ligne
#6 Le 05/07/2012, à 08:33
- jedineofr
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
Bonjour à tous.
D'abord un grand merci !
Toutes vos solutions (mis à part ta premiére sputnick) fonctionnent.
Encore merci et bonne journée
Ubuntu 8.04 LTS -> Ubuntu 8.10 -> Ubuntu 9.04 -> Ubuntu 9.10 -> Ubuntu 10.04 LTS -> Lubuntu 14.04 > Ubuntu 14.04 > Ubuntu 16.04 LTS > Ubuntu 18.04 LTS
Asus ROG G551JW-DM379T (i7 4750HQ, GTX960M, Dd 1 To + SSD 24 Go, Windows 10 + Ubuntu)
Hors ligne
#7 Le 05/07/2012, à 09:30
- Hizoka
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
Moi je propose un sed different et j'en profite pour tester la rapidité sur 1000 lignes
sed "s/.*( \(.*\) ) (.*/\1/" fichier_exemple.txt
temps 0m1.638s
grep -oP '\(\s+\K[[:xdigit:]]+' FILE
real 0m1.430s
awk -F'[()]' '{print $2}' FILE
real 0m1.193s
Dommage qu'il y ait encore les espaces
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#8 Le 05/07/2012, à 09:47
- sputnick
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
Pour awk et l'espace, 2 solutions identiques chez moi en terme de temps :
awk -F'[() ]' '{print $5}' FILE
echo $(awk -F'[()]' '{print $2}' FILE)
@jedineofr si "ça marche pas" ton grep n'a sûrement pas l'option -P qui est pourtant présente sur les Ubuntus de nos jours.
On ne peut pas mettre d'array dans un string!
https://sputnick.fr/
En ligne
#9 Le 05/07/2012, à 14:06
- Hizoka
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
pour savoir si tu as l'option :
grep --help | grep "\-P"
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#10 Le 06/07/2012, à 15:27
- ar barzh paour
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
à méditer ..... les commandes ne sortent que ce qu'on leur demande !!!
contenu du fichier exemple.txt : 8 espaces après le ( et 8 espaces avant le )
File ABZXRW01_GIXRT00_D_NCT03_000_20120704123456.dat ( A12B34567890CDEFGH FIN ) ( ID 069 ) :
OK y compris 8 espaces avant et après
xxx@yyy-desktop:/media/Data_c3/shell$ sed 's/.*(\(.*\)).*(\(.*\)).*/\1/' exemple.txt
A12B34567890CDEFGH FIN
xxx@yyy-desktop:/media/Data_c3/shell$
xxx@yyy-desktop:/media/Data_c3/shell$ grep -oP '\(\s+\K[[:xdigit:]]+' exemple.txt
A12B34567890CDEF
xxx@yyy-desktop:/media/Data_c3/shell$
OK y compris 8 espaces avant et après
xxx@yyy-desktop:/media/Data_c3/shell$ awk -F'[()]' '{print $2}' exemple.txt
A12B34567890CDEFGH FIN
xxx@yyy-desktop:/media/Data_c3/shell$
la commande suivante supprime une espace avant et une espace après
xxx@yyy-desktop:/media/Data_c3/shell$ sed 's/[^(]*( \([^)]*\) ).*/\1/' exemple.txt
A12B34567890CDEFGH FIN
xxx@yyy-desktop:/media/Data_c3/shell$
la commande suivante supprime une espace avant et une espace après
xxx@yyy-desktop:/media/Data_c3/shell$ sed "s/.*( \(.*\) ) (.*/\1/" exemple.txt
A12B34567890CDEFGH FIN
xxx@yyy-desktop:/media/Data_c3/shell$
xxx@yyy-desktop:/media/Data_c3/shell$ grep -oP '\(\s+\K[[:xdigit:]]+' exemple.txt
A12B34567890CDEF
xxx@yyy-desktop:/media/Data_c3/shell$
OK y compris 8 espaces avant et après
xxx@yyy-desktop:/media/Data_c3/shell$ awk -F'[()]' '{print $2}' exemple.txt
A12B34567890CDEFGH FIN
xxx@yyy-desktop:/media/Data_c3/shell$
la commande suivante ne trouve rien
xxx@yyy-desktop:/media/Data_c3/shell$ awk -F'[() ]' '{print $5}' exemple.txt
xxx@yyy-desktop:/media/Data_c3/shell$
xxx@yyy-desktop:/media/Data_c3/shell$ echo $(awk -F'[()]' '{print $2}' exemple.txt)
A12B34567890CDEFGH FIN
xxx@yyy-desktop:/media/Data_c3/shell$
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : ThinkPad P50 I7-6820HQ, 16G0 Ram Ubuntu 22.04 Ubuntu 24.04 , W10-PRO( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#11 Le 07/07/2012, à 08:13
- no_spleen
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
Donner la réponse, c'est bien. Expliquer pourquoi la première solution ne fonctionne pas, c'est mieux !
Jedineofr, il faut savoir que l'opérateur * est "greedy". C'est à dire qua quand tu fais .* il va prendre toute la ligne puis revenir progressivement en arrière jusqu'à ce que ce qui se trouve après le .* dans le regex soit aussi satisfait.
Donc dans ton cas, il va au fond puis en revenant en arrière il tombe sur les deuxièmes paranthèses.
Hors ligne
#12 Le 07/07/2012, à 10:17
- ar barzh paour
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
@ no_spleen
ai-je bien compris ? je veux extraire tout ce qu'il y a entre A et X
dans sed 's/.*A \(.*\) X.* / \1/'
/ .*A \( .* \) X.* / \1 / (les espaces ne sont là que pour la présentation !!!)
| | | |
| | | V
| | | \1 rappel ce qui a été mémorisé la première fois
| V |
| <----------------> | /( .* )/ mémorise ce qu'il y a entre les deux
V V<--------- X.* ne retient que ce qu'il y a avant X
<--------------------------------- .*A ne retient que de A(exclu) à la fin
--A----A-------X-------------X---------- la chaîne originale
si A n'est pas trouvé le résultat est : toute la chaîne
si X n'est pas trouvé le résultat est : toute la chaîne
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : ThinkPad P50 I7-6820HQ, 16G0 Ram Ubuntu 22.04 Ubuntu 24.04 , W10-PRO( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#13 Le 07/07/2012, à 11:43
- UbuntOlivier
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
@ar barzh paour : Bien sûr que les commandes ne retournent que ce qu'on leur demande, d'où l'importance de bien lire l'énoncé… ou de bien exposer le problème, y compris les cas particuliers possibles.
La demande originale de jedineofr était d'extraire les 18 caractères non blancs se trouvant dans la première parenthèse, et non pas de trouver tout ce qu'il y a entre ces parenthèses.
Ton résumé est donc fautif puisqu'il ne tient pas compte correctement de la demande initiale. Toutes les commandes qui conservent les blancs et le mot FIN sont erronées.
S'il s'était agi d'extraire tout ce qu'il y avait entre les premières parenthèses, alors les instructions auraient en effet été différentes… et ton résumé aurait été adapté !
Hors ligne
#14 Le 07/07/2012, à 12:17
- pingouinux
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
Salut,
sed 's/.*A \(.*\) X.* / \1/'
Ta commande recherche les lignes contenant :
n_importe_quoi_debut, A, espace, n_importe_quoi_milieu, espace, X, n_importe_quoi_fin, espace
et remplace cette séquence par :
espace, n_importe_quoi_milieu
Si cette séquence n'est pas trouvée, la ligne initiale est conservée.
Dernière modification par pingouinux (Le 07/07/2012, à 12:18)
Hors ligne
#15 Le 07/07/2012, à 14:12
- ar barzh paour
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
@UbuntOlivier
ce n'était pour moi qu'un exercice de style
je ne voulais seulement voir ce que donnaient ces commandes et comment elles réagissaient
sur des chaînes un peu différentes de celle donnée au post #1
et je dis bravo à vous qui donnez toujours des solutions à un problème
j'aime bien travailler sur des chaînes de caractères
et je butte souvent sur ce type de recherche car je ne connais pas suffisamment ces commandes
à plus
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : ThinkPad P50 I7-6820HQ, 16G0 Ram Ubuntu 22.04 Ubuntu 24.04 , W10-PRO( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#16 Le 07/07/2012, à 16:37
- no_spleen
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
@ar barzh paour
sed 's/.*A \(.*\) X.* / \1/'
Ne fera tout simplement rien, car tu n'a pas de parenthèses de groupement dans ta regex. Il faut plutôt quelque chose comme
sed 's/.*A \( (.* ) \) X.* / \1/'
Cette regex commence par .*, ce qui veux dire "prend le maximum de n'importe quel caractère". Il va donc prendre toute la ligne.
Ensuite, il va regarder si le caractère suivant est bien un A. Ici ce ne sera pas le cas puisque que l'on est en fin de ligne. Il va donc reculer d'un caractère jusqu'à tomber sur un A.
Donc si tu veux le premier A de la ligne et qu'il y en plusieurs, cette regex ne marchera pas car tu auras le dernier de la ligne.
Pour éviter cela, une solution est de remplacer .* par quelque chose comme [^A]*, qui veux dire "prend le plus possible de n'importe quel caractère sauf le A".
Sur certaines implémentations, tu as aussi des opérateurs "non greedy", du genre .*? qui veulent dire "prend le nimimum de n'importe quel caractère". C'est aussi une solution possible au problème.
Dernière modification par no_spleen (Le 07/07/2012, à 16:37)
Hors ligne
#17 Le 07/07/2012, à 17:26
- ar barzh paour
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
oui dans mon post j'ai mis des espaces superflues
sed 's/.*A \(.*\) X.* / \1/'
je voulais mettre
sed 's/.*A\(.*\)X.*/\1/'
qui donne BZXRW01_GI
mais
j'aurais voulu BZ c'est à dire entre 1erA et 1erX
et j'ai
entre 1erA et dernier X
je renonce à comprendre (pour l'instant)
PC : B760M DS3H DDR4, 12th Gen Intel(R) Core(TM) i3-12100, RAM DDR4 8GiB -2400 Ubuntu 20.04, 22.04, 24.04 (en test )
Portable1 : ThinkPad P50 I7-6820HQ, 16G0 Ram Ubuntu 22.04 Ubuntu 24.04 , W10-PRO( en voyage )
Portable2 : T5750 @ 2.00GHz RAM 1GiB DDR2 667 Mhz Ubuntu 20.04 ( batterie HS )
stourm a ran war bep tachenn (Angela Duval) ( Je combats sur tous les fronts )
Hors ligne
#18 Le 07/07/2012, à 17:52
- pingouinux
Re : [RESOLU] [sed] Extraire texte contenu entre parenthèses
j'aurais voulu BZ c'est à dire entre 1erA et 1erX
sed 's/[^A]*A\([^X]*\)X.*/\1/'
Dernière modification par pingouinux (Le 08/07/2012, à 09:32)
Hors ligne