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 21/04/2016, à 00:57

Arbiel

[Résolu] Erreur de "grep" ou incompréhension de ma part ?

Bonsoir

[Edit]
Il s'agit d'une incompréhension de ma part et non d'une erreur de grep, qui recherche, dans une ligne de texte unique, et affiche en sortie toutes les chaînes qui répondent au filtre utilisé et non pas uniquement la première
[/Edit]

Dans une ligne telle que

<dead_iota> <Multi_key> <acute> <dead_psili> <Greek_alpha> 	: "ᾄ"   U1F84 # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI

je cherche les séquences "<dead_qqch1> <dead_qqch2> …". J'ai écrit

dia="$(echo ${l} | sed -re "s/>[[:space:]]*</> </g" | grep -Eo "<dead_[[:alnum:]]+>( <dead_[[:alnum:]]+>)*")";

pour, dans un premier temps m'assurer de la présence d'un espace et d'un seul entre les <dead_qqch>, et dans un deuxième temps afficher la séquence des <dead_qqch>.
J'obtiens

remi@remi-Vostro-3550:~$ l='<dead_iota> <Multi_key> <acute> <dead_psili> <Greek_alpha> : "ᾄ"   U1F84 # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI'
remi@remi-Vostro-3550:~$ dia="$(echo ${l} | sed -re "s/>[[:space:]]*</> </g" | grep -Eo "<dead_[[:alnum:]]+>( <dead_[[:alnum:]]+>)*")";
remi@remi-Vostro-3550:~$ echo $dia
<dead_iota> <dead_psili>
remi@remi-Vostro-3550:~$ 

alors que les <dead_qqch> ne sont pas consécutifs.

Mais la commande fonctionne bien si les <dead_qqch> sont consécutifs

remi@remi-Vostro-3550:~$ l='<dead_iota> <dead_acute> <dead_dasia> <Greek_alpha> : "ᾅ"   U1F85 # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI'
remi@remi-Vostro-3550:~$ dia="$(echo ${l} | sed -re "s/>[[:space:]]*</> </g" | grep -Eo "<dead_[[:alnum:]]+>( <dead_[[:alnum:]]+>)*")";
remi@remi-Vostro-3550:~$ echo $dia
<dead_iota> <dead_acute> <dead_dasia>
remi@remi-Vostro-3550:~$ 

Merci d'avance à quiconque pourra m'indiquer comment contourner le problème.

Arbiel

Dernière modification par Arbiel (Le 22/04/2016, à 00:09)


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#2 Le 21/04/2016, à 01:11

Rufus T. Firefly

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Salut,

"<dead_[[:alnum:]]+>( <dead_[[:alnum:]]+>)*"

à la place, je mettrais :

"<dead_[[:alnum:]]+> <dead_[[:alnum:]]+>"

Mais attends que pingouinux se réveille... Il te fera ça en 3 fois plus court et en plus ça fonctionnera...


La provocation est une façon de remettre la réalité sur ses pieds. (Bertolt Brecht)
Il n'y a pas de route royale pour la science et ceux-là seulement ont chance d'arriver à ses sommets lumineux qui ne craignent pas de se fatiguer à gravir ses sentiers escarpés. (Karl Marx)
Il est devenu plus facile de penser la fin du monde que la fin du capitalisme

Hors ligne

#3 Le 21/04/2016, à 01:42

Watael

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

salut,

il y a quelque chose qui m'échappe ?

$ echo $(grep -o '<dead_[^>]*>' <<<'<dead_iota> <dead_acute> <dead_dasia> <Greek_alpha> : "ᾅ"   U1F85 # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI')
<dead_iota> <dead_acute> <dead_dasia>
$ echo $(grep -o '<dead_[^>]*>' <<< '<dead_iota> <Multi_key> <acute> <dead_psili> <Greek_alpha> : "ᾄ"   U1F84 # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI')
<dead_iota> <dead_psili>
$ 

Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#4 Le 21/04/2016, à 05:59

pingouinux

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Bonjour,
Si j'ai bien compris, je ferais ceci :

$ l='<dead_iota> <Multi_key> <acute> <dead_psili> <Greek_alpha> : "ᾄ"   U1F84 # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI'
$ dia="$(grep -Eo "<dead_[^>]+>([[:space:]]+<dead_[^>]+>)+" <<<"$l")"
$ echo "$dia"

$ l='<dead_iota> <dead_acute> <dead_dasia> <Greek_alpha> : "ᾅ"   U1F85 # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI'
$ dia="$(grep -Eo "<dead_[^>]+>([[:space:]]+<dead_[^>]+>)+" <<<"$l")"
$ echo "$dia"
<dead_iota> <dead_acute> <dead_dasia>

Dernière modification par pingouinux (Le 21/04/2016, à 06:00)

Hors ligne

#5 Le 21/04/2016, à 09:57

Arbiel

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Bonjour

Merci pour vos contributions, mais rien n'y fait.

Ce faisant, je prends conscience que ce n'est pas une erreur de grep. En effet, grep recherche ce qui correspond au filtre autant de fois que nécessaire pour arriver à la fin de la ligne et l'option -o lui demande de l'afficher sur la sortie standard. Si deux séquences correspondent, il les affiche bout à bout, et c'est bien ce qui se passe. Je n'ai pas trouvé le moyen de lui indiquer de limiter le nombre d'applications du filtre. L'option -m, que je n'ai pas essayée, ne me semble pas correspondre à mon besoin, puisqu'elle porte sur le nombre de lignes à traiter et non sur ce nombre d'applications du filtre.

Je pense que je vais devoir utiliser sed pour supprimer tout ce qui entoure la première séquence.

Voyez-vous une autre solution ?

Arbiel

Dernière modification par Arbiel (Le 21/04/2016, à 09:58)


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#6 Le 21/04/2016, à 10:37

pingouinux

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Si le résultat que j'obtiens en #4 n'est pas celui que tu souhaites, peux-tu préciser ce que tu veux ?

Hors ligne

#7 Le 21/04/2016, à 12:35

Arbiel

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

En #4, tu donnes le résultat que je souhaite obtenir, mais sur une ligne pour laquelle je n'avais moi-même pas de difficultés. Par contre si tu appliques ta commande sur la première ligne que j'ai donnée, et que tu as reprises en #4, mais sans présenter le résultat, tu vas obtenir le même résultat que moi, à savoir toutes les occurrences <dead_…> alors que je veux n'obtenir que la séquence ininterrompue de <dead_…>, ceci dans le but de calculer toutes les permutations possibles des éléments de cette séquence.

La production de ces permutations fonctionne. À tout hasard, voilà comment je l'obtiens

	permut () {
		local x="";
		local l="";
		local ne="${1}";
		if [[ $((${#})) -eq 1 ]]; then
			l="${1}" ;
		else
			shift;
# créer toutes les permutations de rang immédiatement inférieur après retrait du premier élément
			for x in $(permut "${@}"); do
# créer deux nouveaux éléments, un avec le premier élément réintroduit en tête, l'autre avec le premier élément réintroduit en queue
				l="${l} ${ne}-${x} ${x}-${ne}";
# jusqu'à ce qu'il n'y ait plus de | dans la suite rendue par le niveau inférieur
				until [[ "${x}" = "${x%|*}" ]]; do
# introduire dans les permutations une nouvelle permutation en remplaçant la première | par la suite "-nouvel_élément-"
					l="${l} ${x/|/-${ne}-}";
# remplacer la première | par un - pour reculer l'insertion du premier élément dans la permutation à suivre
					x="${x/|/-}"
					done;
				done;
# réinsérer des | dans toutes les permutations pour le niveau supérieur
			l=${l//-/|};
		fi;
	echo "${l}"
	}

Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#8 Le 21/04/2016, à 13:07

pingouinux

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Arbiel #7 a écrit :

Par contre si tu appliques ta commande sur la première ligne que j'ai donnée, et que tu as reprises en #4, mais sans présenter le résultat

Le résultat que j'obtiens en #4 pour la première ligne est une chaîne vide. Que voudrais-tu obtenir ?

Hors ligne

#9 Le 21/04/2016, à 13:54

Arbiel

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Oh, pardon. Effectivement tu obtiens une chaîne vide.

Je veux obtenir

<dead_iota>

En fait, il est possible que ce soit aussi bien de chercher la succession d'au moins deux occurrences, ce que fait ta commande (que j'avais mal lue, sans remarquer ton dernier "+" qui vient remplacer mon "*"). En effet, d'une part je ne m'intéresse qu'aux chaînes qui contiennent au moins deux occurrences pour qu'il existe d'autres permutations que celle qui est présente dans la ligne, et d'autre part, la probabilité pour qu'il existe deux fois deux occurrences est extrêmement faible dans l'absolu, et nulle dans mon cas. Je réalise en effet un clavier pour le grec ancien, et, dans cette langue, il n'y a au maximum trois caractères diacritiques par voyelle. Je ne peux donc pas en trouver quatre.

Merci encore pour ton aide.

Et pour en revenir au titre de ma question, il s'agit d'une incompréhension de ma part.

Arbiel


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#10 Le 21/04/2016, à 13:56

Watael

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

pour faire simple, est-ce qu'on pourrait avoir quelques lignes d'exemples (plus que deux !), et la sortie correspondante attendue ?


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#11 Le 21/04/2016, à 14:52

LeoMajor

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Arbiel veut conserver "la succession d'au moins deux occurrences,"
cela va ressembler à un truc du genre

test='<dead_iota> <dead_del> <Multi_key> <acute> <dead_psili> <Greek_alpha> : "ᾄ"   U1F84 # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI'
awk '{for(i=1;i<=NF;i++) if(($i~/dead/) && ($(i-1)~/dead/)){print $i}}' <<< "${test}"
<dead_iota>
<dead_del>

Hors ligne

#12 Le 21/04/2016, à 17:02

Arbiel

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Je vous remercie tous pour l'aide que vous m'avez apportée, mais ne perdez plus votre temps pour me venir en aide sur ce sujet que j'ai indiqué comme résolu.

Pour répondre à vos dernières questions et remarques :

À la réflexion, à partir de l'aide que m'a apportée pingouinux, j'ai modifié ma façon de voir. Voici quelques exemples, dans lesquels j'ai indiqué la ligne de départ commentée de ###. Les autres lignes sont celles que je crée à partir de cette ligne en remplaçant la succession de chaînes de la forme <dead_…> par chacune des autres permutations de cette succession
Dans ce premier exemple, trois chaînes se succèdent (<dead_iota> <dead_grave> <dead_dasia>), ce qui correspond à 6 permutations, et donc à la création de 5 lignes

### <dead_iota> <dead_grave> <dead_dasia> <Greek_alpha> : "ᾃ"   U1F83 # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
<dead_grave> <dead_dasia> <dead_iota> <Greek_alpha> : "ᾃ"   U1F83 # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI )
<dead_grave> <dead_iota> <dead_dasia> <Greek_alpha> : "ᾃ"   U1F83 # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI )
<dead_iota> <dead_dasia> <dead_grave> <Greek_alpha> : "ᾃ"   U1F83 # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI )
<dead_dasia> <dead_grave> <dead_iota> <Greek_alpha> : "ᾃ"   U1F83 # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI )
<dead_dasia> <dead_iota> <dead_grave> <Greek_alpha> : "ᾃ"   U1F83 # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI )

Dans cet exemple, deux chaînes se succèdent (<dead_tilde> <dead_dasia>), ce qui correspond à deux permutations et donc à la création d'une seule ligne

### <Multi_key> <Greek_iota> <dead_tilde> <dead_dasia> <Greek_alpha> : "ᾇ"   U1F87 # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
<Multi_key> <Greek_iota> <dead_dasia> <dead_tilde> <Greek_alpha> : "ᾇ"   U1F87 # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI )

Initialement, mais aussi stupidement, je voulais aussi traiter une ligne telle que

### <dead_acute> <Greek_alpha>       	: "ά"   U03AC # GREEK SMALL LETTER ALPHA WITH TONOS

Mais comme il n'y a qu'une seule chaîne <dead_acute>, il n'y a pas d'autre permutation, et donc pas de ligne à créer.

Dans cette vision des choses j'étais gêné par des lignes telles que

### <dead_iota> <Multi_key> <acute> <dead_psili> <Greek_alpha> : "ᾄ"   U1F84 # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI

pour lesquelles grep me donne "<dead_iota> <dead_psili>" parce que je ne sais pas permuter des éléments qui ne sont pas adjacents.

Tout ceci se situe dans le contexte de la création d'un clavier pour la saisie de grec ancien fondé sur bépo et non sur qwerty, comme l'est le clavier grec ancien (polytonique) de la distribution. Les lignes que je crée ont comme but de permettre la saisie des diacritiques à partir des touches muettes dans n'importe quel ordre et non pas dans le seul ordre défini dans le fichier adéquat.

Deux autres points

1) je ne connais pas la syntaxe de awk, et suis donc incapable d'utiliser ce programme

2) dans mon petit script, l'utilisation d'un "here string" (<<< ${l}) cause de nombreux dégâts, probablement du fait de redirections d'entrée-sortie que je maîtrise mal, le texte

Bash Reference Manual a écrit :

Note that the order of redirections is significant. For example, the command

     ls > dirlist 2>&1

directs both standard output (file descriptor 1) and standard error (file descriptor 2) to the file dirlist, while the command

     ls 2>&1 > dirlist

directs only the standard output to file dirlist, because the standard error was made a copy of the standard output before the standard output was redirected to dirlist.

ne m'est pas clair du tout, comme ne m'est pas clair non plus

Bash Reference Manual a écrit :

Each redirection that may be preceded by a file descriptor number may instead be preceded by a word of the form {varname}. In this case, for each redirection operator except >&- and <&-, the shell will allocate a file descriptor greater than 10 and assign it to {varname}. If >&- or <&- is preceded by {varname}, the value of varname defines the file descriptor to close.

Pour terminer, et si vous êtes intéressé, voici mon script, qui maintenant, me semble parfaitement fonctionner

#! /bin/bash
	permut () {
		local x="";
		local l="";
		local ne="${1}";
		if [[ $((${#})) -eq 1 ]]; then
			l="${1}" ;
		else
			shift;
# créer toutes les permutations de rang immédiatement inférieur après retrait du premier élément
			for x in $(permut "${@}"); do
# créer deux nouveaux éléments, un avec le premier élément réintroduit en tête, l'autre avec le premier élément réintroduit en queue
				l="${l} ${ne}-${x} ${x}-${ne}";
# jusqu'à ce qu'il n'y ait plus de | dans la suite rendue par le niveau inférieur
				until [[ "${x}" = "${x%|*}" ]]; do
# introduire dans les permutations une nouvelle permutation en remplaçant la première | par la suite "-nouvel_élément-"
					l="${l} ${x/|/-${ne}-}";
# remplacer la première | par un - pour reculer l'insertion du premier élément dans la permutation à suivre
					x="${x/|/-}"
					done;
				done;
# réinsérer des | dans toutes les permutations pour le niveau supérieur
			l=${l//-/|};
		fi;
	echo "${l}"
	}

	traite_ligne () {
# normaliser la ligne pour séparer les références aux muettes par un et un seul espace et extraire la succession de muettes
		dia="$(echo ${l} | sed -re "s/>[[:space:]]*</> </g" | grep -Eo "<dead_[^>]+>( <dead_[^>]+>)+")";
		echo "### ${l}";
		canevas="$(echo "${l}" | sed -re "s/${dia}/…/") )";
		for diacritiques in $(permut ${dia}); do
			diacritiques="${diacritiques//|/ }";
# ne pas introduire de ligne identique à la ligne présente dans le fichier
			! [[ "${diacritiques}" = "${dia}" ]] && echo "${canevas}" | sed -e "s/…/${diacritiques}/";
			done;
		return 0;
		}			
		
	traitement () {
		while read l; do
# ne traiter que les lignes qui correspondent à des lettres grecques avec au moins deux diacritiques successifs
			echo "${l}" | grep -E "<dead_[^>]+>([[:space:]]+<dead_[^>]+>)+.* GREEK " 1>/dev/null && traite_ligne
		done;
	}
		

Arbiel


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#13 Le 21/04/2016, à 17:25

pingouinux

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

@LeoMajor #11 :
Si le premier champ contient dead, ta commande va déclencher une sortie, même s'il n'y en a pas d'autre, car tu testes dans ce cas $1 et $0.

Ajouté : De plus, si les dead consécutifs ne sont pas en début de ligne, le premier est omis.

Dernière modification par pingouinux (Le 22/04/2016, à 06:09)

Hors ligne

#14 Le 21/04/2016, à 17:34

pingouinux

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Arbiel #12 a écrit :

dans mon petit script, l'utilisation d'un "here string" (<<< ${l}) cause de nombreux dégâts, probablement du fait de redirections d'entrée-sortie

Peux-tu montrer le passage qui te donne du souci ?

Hors ligne

#15 Le 22/04/2016, à 00:08

Arbiel

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Bonsoir

@pingouinux
Désolé, j'ai jeté la version du script qui me posait problème.

J'ai de nouveau remplacé tous les pipelines "echo _ | sed ou grep" par des "here_string", mais cela n'a eu aucun effet négatif sur le script. Je suis donc tout à fait incapable de reproduire le fonctionnement défectueux, et donc de t'indiquer ce qui ne fonctionnait pas.

Voila ce que j'avais constaté :

dès la détection de la première ligne à traiter par la commande du while read l do, alors rédigée ainsi

grep -E "<dead_[^>]+>([[:space:]]+<dead_[^>]+>)+.* GREEK " 1>/dev/null <<< "${l}" && traite_ligne

j'obtenais la sortie de la ligne avec la commande

		echo "### ${l}";

immédiatement suivie de toutes les lignes qui venaient derrière, qui n'avaient pas à être traitées et qui me semblaient provenir de la commande de test de traitement, comme si la commande echo "### …" avait eu comme effet de supprimer la redirection "1>/dev/null".
Mais comme cela ne se produit plus, j'imagine que j'avais fait une autre erreur, corrigée en remplaçant les "here_strings" par des pipelines, erreur que je n'ai pas reproduite à l'instant en voulant revenir à la version défectueuse.

Arbiel


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#16 Le 22/04/2016, à 06:02

pingouinux

Re : [Résolu] Erreur de "grep" ou incompréhension de ma part ?

Pour info, le paramètre -q de grep supprime la sortie standard, ce qui évite la redirection.

Hors ligne