Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

grep - remplacer une succession de pipes

2 views
Skip to first unread message

yves

unread,
Jan 3, 2024, 10:46:31 AM1/3/24
to
Bonjour (et bonne année).

sous ubuntu /usr/share/dict/french est un fichier de 346200 lignes
installé par le paquet wfrench

#+begin_src sh :results output
apt-cache search wfrench |grep -v forensics
wc -l /usr/share/dict/french
#+end_src

#+RESULTS:
: wfrench - dictionnaire de mots français pour /usr/share/dict
: 346200 /usr/share/dict/french

-----------------------

Cette commande :

#+begin_src sh
grep -vc [abcdef] /usr/share/dict/french
#+end_src

#+RESULTS:
: 6904

retourne le nombre (option -c) de lignes qui ne contiennent (option
-v) ni a ni b ni c ni de ni e ni f

-----------------------

Cette commande :

#+begin_src sh
grep -vc [a-s] /usr/share/dict/french
#+end_src

#+RESULTS:
: 18

retourne le nombre de lignes qui ne contiennent aucune des lettres de
a à s

---------------------

Cette commande :

#+begin_src sh
cat /usr/share/dict/french|grep a|grep b |grep c| grep d|grep e|grep f
#+end_src

#+RESULTS:
| acidifiable |
| déchiffrable |
| déchiffrables |
| défrichable |
| différenciable |
| différenciables |
| fécondable |
| indéchiffrable |
| indéchiffrables |
| indéfrichable |
| indéfrichables |

retourne les (11) lignes qui contiennent à la fois a et b et c et d et
e et f

Existe-t-il une syntaxe qui évite cette succession de pipes ( |grep
a|grep b| grep c ....etc...) ?

@+
--
Yves

Olivier Miakinen

unread,
Jan 3, 2024, 12:45:32 PM1/3/24
to
Le 03/01/2024 à 16:46, yves a écrit :
>
> Cette commande :
>
> #+begin_src sh
> cat /usr/share/dict/french|grep a|grep b |grep c| grep d|grep e|grep f
> #+end_src
>
> #+RESULTS:
> | acidifiable |
> | déchiffrable |
> | déchiffrables |
> | défrichable |
> | différenciable |
> | différenciables |
> | fécondable |
> | indéchiffrable |
> | indéchiffrables |
> | indéfrichable |
> | indéfrichables |
>
> retourne les (11) lignes qui contiennent à la fois a et b et c et d et
> e et f
>
> Existe-t-il une syntaxe qui évite cette succession de pipes ( |grep
> a|grep b| grep c ....etc...) ?

Oui, avec les regexp de type perl (pcre) et les assertions. Je n'ai pas
le temps tout de suite mais je te répondrai plus tard.


--
Olivier Miakinen

Olivier Miakinen

unread,
Jan 3, 2024, 1:03:22 PM1/3/24
to
Le 03/01/2024 à 18:45, je répondais à yves :
>>
>> Cette commande :
>>
>> #+begin_src sh
>> cat /usr/share/dict/french|grep a|grep b |grep c| grep d|grep e|grep f
>> #+end_src
>>
>> [...]
>>
>> Existe-t-il une syntaxe qui évite cette succession de pipes ( |grep
>> a|grep b| grep c ....etc...) ?
>
> Oui, avec les regexp de type perl (pcre) et les assertions. Je n'ai pas
> le temps tout de suite mais je te répondrai plus tard.

Finalement j'ai eu le temps.

grep -P '(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f).' \
/usr/share/dict/french


--
Olivier Miakinen

Olivier Miakinen

unread,
Jan 3, 2024, 1:12:29 PM1/3/24
to
Le 03/01/2024 à 19:03, Olivier Miakinen a écrit :
>
> grep -P '(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f).' \
> /usr/share/dict/french

acidifiable
déchiffrable
déchiffrables
défrichable
différenciable
différenciables
fécondable
indéchiffrable
indéchiffrables
indéfrichable
indéfrichables

grep -P '(?=.*[aàâ])(?=.*b)(?=.*[cç])(?=.*d)(?=.*[eéèëê])(?=.*f).' \
/usr/share/dict/french

acidifiable
déchiffrable
déchiffrables
défrichable
différenciable
différenciables
fécondabilité
fécondable
indéchiffrable
indéchiffrables
indéfrichable
indéfrichables

(on y a gagné "fécondabilité")

--
Olivier Miakinen

Olivier Miakinen

unread,
Jan 3, 2024, 1:27:36 PM1/3/24
to
Le 03/01/2024 à 19:12, Olivier Miakinen a écrit :
>
> grep -P '(?=.*[aàâ])(?=.*b)(?=.*[cç])(?=.*d)(?=.*[eéèëê])(?=.*f).' \
> /usr/share/dict/french
>
> acidifiable
> déchiffrable
> déchiffrables
> défrichable
> différenciable
> différenciables
> fécondabilité
> fécondable
> indéchiffrable
> indéchiffrables
> indéfrichable
> indéfrichables
>
> (on y a gagné "fécondabilité")

Si c'est toujours pour "tricher" au scrabble, tu peux aussi ignorer les
accents, auquel cas la commande grep devient plus simple :

iconv -f UTF-8 -t ASCII//TRANSLIT /usr/share/dict/french \
| uniq | grep -P '(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f).'

acidifiable
dechiffrable
dechiffrables
defrichable
differenciable
differenciables
fecondabilite
fecondable
indechiffrable
indechiffrables
indefrichable
indefrichables

(bien sûr tu peux faire le 'iconv | uniq' une fois pour toute, avec
résultat dans un fichier qui te servira ensuite pour les 'grep')

--
Olivier Miakinen

Olivier Miakinen

unread,
Jan 4, 2024, 4:14:31 AM1/4/24
to
(On ne m'arrête plus)

Le 03/01/2024 à 19:27, Olivier Miakinen a écrit :
>
> Si c'est toujours pour "tricher" au scrabble, tu peux aussi ignorer les
> accents, auquel cas la commande grep devient plus simple :
>
> iconv -f UTF-8 -t ASCII//TRANSLIT /usr/share/dict/french \
> | uniq | grep -P '(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f).'
>
> acidifiable
> dechiffrable
> dechiffrables
> defrichable
> differenciable
> differenciables
> fecondabilite
> fecondable
> indechiffrable
> indechiffrables
> indefrichable
> indefrichables

Tu peux aussi chercher les résultats avec deux fois la lettre f, en
remplaçant (?=.*f) par (?=.*f.*f) :

iconv -f UTF-8 -t ASCII//TRANSLIT /usr/share/dict/french | uniq \
| grep -P '(?=.*a)(?=.*b)(?=.*c)(?=.*d)(?=.*e)(?=.*f.*f).'

dechiffrable
dechiffrables
differenciable
differenciables
indechiffrable
indechiffrables

(je te laisse deviner comment faire pour une lettre présente trois
fois ou plus)

> (bien sûr tu peux faire le 'iconv | uniq' une fois pour toute, avec
> résultat dans un fichier qui te servira ensuite pour les 'grep')

+1


--
Olivier Miakinen

yves

unread,
Jan 4, 2024, 7:43:48 AM1/4/24
to
Le Wed, 3 Jan 2024 19:12:27 +0100, Olivier Miakinen a écrit:

Olivier Miakinen <om+...@miakinen.net> writes:

> Si c'est toujours pour "tricher" au scrabble, tu peux aussi ignorer les
> accents, auquel cas la commande grep devient plus simple :

Merci.

C'est pour tricher au wordle, un jeu où l'on a 6 essais pour
découvrir un mot de 5 lettres.

Pour ceux qui ne connaissent pas :

<https://wordle.louan.me/>

Si besoin, j'utilise une combine quand je suis bloqué trop longtemps (à
mon goût), qui consiste à exécuter une adaptation de la commande
suivante :

#+BEGIN_SRC sh
grep "^[^b|^A-Z]\w\w\w[^eéèëê]$" /usr/share/dict/french |grep r|grep r|grep s|grep -vc [toinp]
#+END_SRC

Ça marche bien, mais depuis un moment, ça m'agaçait de ne pas trouver
une autre syntaxe que cette succession de pipes pour les mots qui contiennent
r et s, alors que le grep -v [toinp] marche bien pour selectionner des
mots qui ne contiennent pas t,o,i,n,p.

@+
--
Yves

Olivier Miakinen

unread,
Jan 4, 2024, 10:39:39 AM1/4/24
to
Le 04/01/2024 à 13:43, yves a écrit :
>
> #+BEGIN_SRC sh
> grep "^[^b|^A-Z]\w\w\w[^eéèëê]$" /usr/share/dict/french
> #+END_SRC
Je ne comprends pas à quoi sert [^b|^A-Z]. Cette syntaxe dit que tu veux
un caractère qui ne soit :
- ni un 'b'
- ni un '|'
- ni un '^'
- ni une lettre majuscule entre A et Z

Or dans /usr/share/dict/french il y a bien des mots avec un 'b', mais
aucun avec un '|', ni avec un '^', ni avec une lettre majuscule. Ainsi,
l'expression serait exactement la même si tu écrivais juste [^b]

--
Olivier Miakinen

yves

unread,
Jan 4, 2024, 12:05:16 PM1/4/24
to
Oui, effectivement, il n'y a pas de mots qui commencent avec une
majuscule dans /usr/share/dict/french.

C'est parce qu'il y a aussi des wordles en anglais, et que dans le
dictionnaire
/usr/share/dict/american-english, il y a des mots qui commencent par des
majuscules.

#+BEGIN_SRC sh
#grep "^[A-Z]\w\w\w\w$" /usr/share/dict/american-english |grep -vc [toinp]
grep "^[^a|^A-Z]\w\w\w\w$" /usr/share/dict/american-english |head
#+END_SRC

En fait , par exemple :
grep "^[^a|^A-Z]\w\w\w\w$"

ce que (je crois que) dit la ligne [^a|^A-Z] , c'est que je veux un
caractère:
qui ne soit:
- ni un 'a'
- ni une majuscule entre A et Z

grep "^[^a|^A-Z]\w\w\w\w$" /usr/share/dict/american-english |head

La ligne complète ci-dessus donne les dix premiers mots qui ne
commence ni par a ni par une majuscule entre A et Z, et qui ont 5
lettres dans le /usr/share/dict/american-english

@+
--
Yves

Olivier Miakinen

unread,
Jan 4, 2024, 2:28:36 PM1/4/24
to
Le 04/01/2024 à 18:05, yves a écrit :
>
> ce que (je crois que) dit la ligne [^a|^A-Z] , c'est que je veux un
> caractère:
> qui ne soit:
> - ni un 'a'
> - ni une majuscule entre A et Z

Pas exactement. Pour ce que tu veux faire (ni un 'a' ni une majuscule),
c'est [^aA-Z] ou [^A-Za].

Si tu écris [^a|^A-Z], alors c'est « ni un 'a', ni une majuscule, ni un
'^', ni un '|' ». En effet, dans une classe de caractères entre [], le
caractère '|' est un caractère normal n'importe où, et le caractère '^'
est un caractère normal n'importe où sauf au tout début.

Par exemple, [|^] veut dire « soit '|' soit '^' », tandis que [^|^] veut
dire « n'importe quoi sauf '|' ou '^' ».

--
Olivier Miakinen

yves

unread,
Jan 4, 2024, 2:43:17 PM1/4/24
to
Le Thu, 4 Jan 2024 20:28:34 +0100, Olivier Miakinen a écrit:

> Pas exactement. Pour ce que tu veux faire (ni un 'a' ni une majuscule),
> c'est [^aA-Z] ou [^A-Za].
>
> Si tu écris [^a|^A-Z], alors c'est « ni un 'a', ni une majuscule, ni un
> '^', ni un '|' ». En effet, dans une classe de caractères entre [], le
> caractère '|' est un caractère normal n'importe où, et le caractère '^'
> est un caractère normal n'importe où sauf au tout début.
>
> Par exemple, [|^] veut dire « soit '|' soit '^' », tandis que [^|^] veut
> dire « n'importe quoi sauf '|' ou '^' ».

Merci, je vais corriger mes formules et compléter mes notes personnelles.

@+
--
Yves
0 new messages