Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Grep avec bash: proteger les doubles guillemets

7 réponses
Avatar
Apokrif
Bonjour,

J'ai un fichier qui ressemble à ça:

internet
"internet


et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je
veux 'internet' mais pas '"internet'). La première chose qui vient à
l'idée, c'est '$ grep [^"]i foobar', mais évidemment les guillemets
ont une signification spéciale pour grep et/ou pour bash, donc ça ne
marche pas. J'ai essayé plusieurs syntaxes pour que les guilemets
soient considérés comme des caractères normaux:

$ grep '[^"]nte' foobar
internet
"internet"

$ grep '[^\"]nte' foobar
internet
"internet"

$ grep [^\"] foobar
internet
"internet"

$ grep '[^\\"]nte' foobar
internet
"internet"

et d'autres variantes. A chaque fois j'obtiens la ligne cherchée, mais
*aussi* celle que je ne veux pas. D'autre part, je ne comprends pas
pourquoi j'obtiens deux lignes de résultats avec 'grep [^\"] foobar'
alors que 'grep [^\"]i foobar' ne renvoie aucun résultat.

7 réponses

Avatar
Fred
Bonjour,

J'ai un fichier qui ressemble à ça:

internet
"internet


et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je
veux 'internet' mais pas '"internet'). La première chose qui vient à
l'idée, c'est '$ grep [^"]i foobar', mais évidemment les guillemets
ont une signification spéciale pour grep et/ou pour bash, donc ça ne
marche pas. J'ai essayé plusieurs syntaxes pour que les guilemets
soient considérés comme des caractères normaux:

$ grep '[^"]nte' foobar
internet
"internet"

$ grep '[^"]nte' foobar
internet
"internet"

$ grep [^"] foobar
internet
"internet"

$ grep '[^"]nte' foobar
internet
"internet"

et d'autres variantes. A chaque fois j'obtiens la ligne cherchée, mais
*aussi* celle que je ne veux pas. D'autre part, je ne comprends pas
pourquoi j'obtiens deux lignes de résultats avec 'grep [^"] foobar'
alors que 'grep [^"]i foobar' ne renvoie aucun résultat.


La première idée qui me vient est d'utiliser :

cat fichier | sed -e 's/^".*$//' | grep internet

A+
Fred

Avatar
Stéphane Goujet
J'ai un fichier qui ressemble à ça:
internet
"internet
et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je
veux 'internet' mais pas '"internet').
$ grep '[^"]nte' foobar
$ grep '[^"]nte' foobar
$ grep [^"] foobar
$ grep '[^"]nte' foobar


Et :

$ grep ^[^"]i foobar

pour ancrer au début de la ligne ?

et d'autres variantes. A chaque fois j'obtiens la ligne cherchée, mais
*aussi* celle que je ne veux pas. D'autre part, je ne comprends pas
pourquoi j'obtiens deux lignes de résultats avec 'grep [^"] foobar'


Je pense que c'est parce que il suffit qu'il y ait un caractère
différent de guillemet dans la ligne pour satisfaire la condition.
Vous pouvez obtenir le résultat que vous croyiez obtenir en faisant :
$ grep -v " foobar

A+,
Stéphane.

Avatar
Pascal Bourguignon
Apokrif writes:

Bonjour,

J'ai un fichier qui ressemble à ça:

internet
"internet


et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je
veux 'internet' mais pas '"internet'). La première chose qui vient à
l'idée, c'est '$ grep [^"]i foobar', mais évidemment les guillemets
ont une signification spéciale pour grep et/ou pour bash, donc ça ne
marche pas. J'ai essayé plusieurs syntaxes pour que les guilemets
soient considérés comme des caractères normaux:

$ grep '[^"]nte' foobar
internet


normal, i n'est pas un ", donc [^"]nte matches inte


"internet"


normal, i n'est pas un ", donc [^"]nte matches inte


$ grep '[^"]nte' foobar
internet


normal, i n'est pas un ni un ", donc [^"]nte matches inte


"internet"


normal, i n'est pas un ni un ", donc [^"]nte matches inte


$ grep [^"] foobar
internet


normal, i n'est pas un ", donc [^"] matches i


"internet"


normal, i n'est pas un ", donc [^"] matches i


$ grep '[^"]nte' foobar
internet


normal, i n'est pas un ni un ", donc [^"]nte matches inte


"internet"


normal, i n'est pas un ni un ", donc [^"]nte matches inte


et d'autres variantes. A chaque fois j'obtiens la ligne cherchée, mais
*aussi* celle que je ne veux pas. D'autre part, je ne comprends pas
pourquoi j'obtiens deux lignes de résultats avec 'grep [^"] foobar'


Parce qu'aucune ligne ne contient qu'un caractère ".


alors que 'grep [^"]i foobar' ne renvoie aucun résultat.


Parce qu'aucune ligne ne contient un caractère qui ne soit pas " suivit d'un i.




Faudrait apprendre à construire des expressions regulières...

man 7 regex


et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je


Quoi ne doit pas commencer par " ? La ligne ou la chaine?

Une ligne qui contient une chaine donnée:

grep '^.*internet.*$' foobar


Une ligne qui contient une chaine donnée, cette chaine n'étant pas
préfixée d'un ":

grep '^(.*[^"]|)internet.*$' foobar

Une ligne qui ne commence pas par " et qui contient une chaine donnée:

grep '^([^"].*|)internet.*$' foobar



Un problème avec grep (et la plupart des programes utilisant des
expressions régulières), c'est que lorsqu'on ancre pas l'expression E,
elle est prise automatiquement comme: ^.*E.*$
Si l'on pert de vue ce fait, on n'y comprend rien...




--
__Pascal Bourguignon__ http://www.informatimago.com/

Avatar
Jacques L'helgoualc'h
Le 02-03-2005, Fred a écrit :
Bonjour,



bonjour,

[...]
La première idée qui me vient est d'utiliser :

cat fichier | sed -e 's/^".*$//' | grep internet


Bah oui, mais non, c'est un UUOC et un UUO[SG] ...

<fichier sed -e '/^"/d
/internet/p'

(pas de " au début de la ligne, avec la chaîne internet n'importe où)
--
Jacques L'helgoualc'h


Avatar
Jacques L'helgoualc'h
Le 02-03-2005, Fred a écrit :
Bonjour,



bonjour,

[...]
La première idée qui me vient est d'utiliser :

cat fichier | sed -e 's/^".*$//' | grep internet


Bah oui, mais non, c'est un UUOC et un UUO[SG] ...

<fichier sed -e '/^"/d
/internet/!d'

(pas de " au début de la ligne, avec la chaîne internet n'importe où)
--
Jacques L'helgoualc'h


Avatar
seisen
Apokrif writes:

et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je
veux 'internet' mais pas '"internet').


cat foobar | grep internet | grep -v '^"'

--
GnuPG ID 1024D/112189D8

Avatar
Pascal Bourguignon
writes:

Apokrif writes:

et je voudrais avec grep récupérer les lignes qui contiennent une
chaîne donnée mais qui ne commencent pas par '"' (dans cet exemple, je
veux 'internet' mais pas '"internet').


cat foobar | grep internet | grep -v '^"'
cat < foobar |cat| grep .| sed -e 's/a/a/' |cat | grep internet | grep -v '^"'


--
__Pascal Bourguignon__ http://www.informatimago.com/

Nobody can fix the economy. Nobody can be trusted with their finger
on the button. Nobody's perfect. VOTE FOR NOBODY.