Rechercher : dans
Par :

GREP nombre impair

Dernière réponse le 9 mai 2009 à 17:39:42 eZula, le 5 avr 2009 à 15:55:25 
 Signaler ce message aux modérateurs

Salut,

Pour déboguer un batch DOS, je cherche à matcher des lignes foireuses, par exemple celles qui pourraient contenir un guillemet suivi de n'importe quelle expression sauf un guillemet. Aucun de mes essais n'a abouti à qque chose de valable.
Finalement, encore plus intéressant, j'ai pensé plutôt à matcher ttes les lignes d'un fichier qui contiennent un nombre impair de guillemets

"coucou"
cou"cou
cou""cou
coucou"
"couco"u"


donc ici lignes 2, 4 et 5. Y a-t-il, avec l'option -c par exemple une solution à ce problème sans passer par aucune autre commande Linux (en dehors de SED à la rigueur) ?
Ce serait bien aussi de caser l'option -n pour avoir l'affichage des lignes et de leurs numéros

Je suis également intéressé par une regexp correspondant au premier essai (simple curiosité)

Merci
Configuration: Windows XP
Firefox 3.0.8

Meilleures réponses pour « GREP nombre impair » dans :
Vérifier si un nombre entier est un nombre premier en C VoirDéfinition nombre premier Algorithme 1 : les diviseurs compris entre 2 et N-1 seront testés Algorithme 2 : les diviseurs pairs ne seront pas testés, la recherche se limitant aux diviseurs impairs Algorithme 3 : les diviseurs impairs jusqu'à la...
[Word] Écrire un nombre en toutes lettres VoirPour transformer un nombre en toutes lettres sans se perdre dans l'orthographe (tirets, 's'...), il est possible de demander à Word de formater ce nombre en lettres : Créer un champ avec CTRL-F9 S'affichera {} à l'écran Le remplir avec la...
[PHP] Dernier jour du mois / Nombre de jours dans le mois VoirSoient $m le numéro du mois en question et $y l'année. La fonction date() permet d'afficher directement le nombre de jours dans le mois avec le caractère "t" :
Représentation des nombres entiers et réels VoirReprésentation d'un nombre dans un ordinateur On appelle représentation (ou codification) d'un nombre la façon selon laquelle il est décrit sous forme binaire. La représentation des nombres sur un ordinateur est indispensable pour que celui-ci...
Tableur - Les fonctions mathématiques VoirLes fonctions standards Méthode description ABS() Cette méthode renvoie la valeur absolue d'un nombre, il renvoie donc le nombre s'il est positif, son opposé (positif) s'il est négatif IMPAIR(valeur) Cette méthode renvoie la valeur...

1

jipicy, le 5 avr 2009 à 19:02:33

Salut,

J'ai torturé 'grep" dans tous les sens, mais je n'ai rien pu en tirer ;-(((

Une solution avec "sed" :

[tmpfs]$ cat -n plop
     1  "coucou"
     2  cou"cou
     3  cou""cou
     4  coucou"
     5  "cou"cou"
     6  "cou"c"o"u

[tmpfs]$ cat -n plop | sed -n 'h;:z;/"/{s/\("[^"]*"\)//1;tz;g;p}'
     2  cou"cou
     4  coucou"
     5  "cou"cou"

[tmpfs]$
Si tu ne veux pas du "cat -n" remplace-le par :
sed = plop | sed 'N;s/\n/ - /' |
;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

2

mamiemando, le 5 avr 2009 à 19:02:36

Faisable avec sed. Le cut ne sert qu'à extraire le numéro de ligne.

(mando@aldur) (~) $ cat plop.txt
"coucou"
cou"cou
cou""cou
coucou"
"couco"u"

(mando@aldur) (~) $ cat plop.txt | sed -e s/\"[^\"]*\"//g | grep -n "\"" | cut -f1 -d:
2
4
5

Bonne chance

Répondre à mamiemando

3

jipicy, le 5 avr 2009 à 19:05:33

Chapeau bas Miss (comme dirait lami20j) ;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

4

mamiemando, le 5 avr 2009 à 19:12:19

Merci :-) Mais bon le sed modifie la ligne. Mon approche consiste à virer les "xxx". Du coup si le nombre de guillemets est impair, il en reste un après le sed et le dernier grep extrait la ligne (modifiée donc).

Bref c'est pas complètement parfait, car je ne vois pas comment avoir simplement le numéro de ligne + la ligne complète sans passer par un script (il faudrait stocker la ligne lue et la réécrire si la ligne matche).

Répondre à mamiemando

5

eZula, le 5 avr 2009 à 20:01:06

Merci :)

le malheur dans tout ça c'est que c'est sous windows comme d'habitude, c'est pour cela que j'ai précisé "sans autre commande Linux, j'ai juste sed, grep et uniq). La seule approche à peu près ressemblante que je vois c'est

for /f "tokens=*" %%A IN (Path.txt) DO ECHO %%A | sed -e "s/\"[^\"]*\"//g" | grep -n "\""


voilà l'interprétation :

>for /F "tokens=*" %A IN (Path.txt) DO ECHO %A   | sed -e "s/\"[\"]*\"//g" | grep -n "\""

>ECHO "coucou"   | sed -e "s/\"[\"]*\"//g" | grep -n "\""
sed: can't read |: Invalid argument
sed: can't read grep: No such file or directory
sed: can't read ": Invalid argument
Le processus a tenté d'écrire sur un canal inexistant.

>ECHO cou"cou   | sed -e "s/\"[\"]*\"//g" | grep -n "\""
sed: can't read |: Invalid argument
sed: can't read grep: No such file or directory
sed: can't read ": Invalid argument
Le processus a tenté d'écrire sur un canal inexistant.

>ECHO cou""cou   | sed -e "s/\"[\"]*\"//g" | grep -n "\""
sed: can't read |: Invalid argument
sed: can't read grep: No such file or directory
sed: can't read ": Invalid argument
Le processus a tenté d'écrire sur un canal inexistant.

>ECHO coucou"   | sed -e "s/\"[\"]*\"//g" | grep -n "\""
sed: can't read |: Invalid argument
sed: can't read grep: No such file or directory
sed: can't read ": Invalid argument
Le processus a tenté d'écrire sur un canal inexistant.

>ECHO "couco"u"   | sed -e "s/\"[\"]*\"//g" | grep -n "\""
sed: can't read |: Invalid argument
sed: can't read grep: No such file or directory
sed: can't read ": Invalid argument
Le processus a tenté d'écrire sur un canal inexistant.

>ECHO ~%%i   | sed -e "s/\"[\"]*\"//g" | grep -n "\""
sed: can't read |: Invalid argument
sed: can't read grep: No such file or directory
sed: can't read ": Invalid argument
Le processus a tenté d'écrire sur un canal inexistant.


j'utilise ce sed http://gnuwin32.sourceforge.net/packages/sed.htm 4.1.5

Le fait d'écrire un script après comme suggéré ne serait pas contraignant, le vrai souci c'est d'arriver à encadrer ce motif qui parait tout simple :)

Répondre à eZula

6

mamiemando, le 5 avr 2009 à 20:02:41
  • +1

Pourquoi ne pas simplement installer cygwin ?

Répondre à mamiemando

7

jipicy, le 5 avr 2009 à 21:31:38

Ma solution au post #1 ne va pas ?
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

8

eZula, le 5 avr 2009 à 21:38:19

J'ai bidouillé ta commande comme ceci :

>grep -n "." Path.txt | sed -n "h;:z;/\"/{s/\(\"[^\"]*\"\)//1;tz;g;p}"
2:cou"cou
4:coucou"
5:"couco"u"

merde, ça a l'air bon ? :))

Répondre à eZula

9

eZula, le 5 avr 2009 à 21:54:08

Excuse, mais tu pourrais expliciter cette expression régulière sed, s'il te plait ?

Merci

Répondre à eZula

10

jipicy, le 5 avr 2009 à 22:28:22

#n                      # Affichage sur demande
h                       # On stocke la ligne dans la mémoire annexe
:z                      # Étiquette
/"/ {                   # Si on trouve un guillemet 
    s/\("[^"]*"\)//1    # On essaie de substituer tout ce qui se
                        # trouve entre 2 guillemets par rien
    t z                 # Si une substitution a eu lieu on se branche
                        # à l'étiquette et on remet ça
    g                   # Sinon (qu'un guillemet restant) on remet
                        # la ligne stockée dans la mémoire secondaire
                        # dans l'espace de travail
    p                   # Et on l'imprime
}
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

12

eZula, le 5 avr 2009 à 22:35:23

Super, merci encore ;)

j'applique ton modèle à d'autres problèmes possibles, et je rencontre une autre difficulté, pour une situation quasi-identique : nombre impair de % (exemple de ligne : utryu%uio)

grep -n "." Path.txt | sed -n "h;:z;/%/{s/\(%[^%]*%\)//1;tz;g;p}"


ça ne fonctionne pas, même en protégeant le % avec un antislash, tu aurais une idée ? car comme précisé avec d'autres caractères recherchés, tel que le ^, et une fois protégé,

>grep -n "." Path.txt   | sed -n "h;:z;/\^/{s/\(\^[^\^]*\^\)//1;tz;g;p}"
8:cou^cou


le motif est bien trouvé.

Répondre à eZula

13

jipicy, le 5 avr 2009 à 23:04:17

[tmpfs]$ cat plop
%coucou%
cou%cou
cou%%cou
coucou%
%cou%cou%
%cou%c%o%u

[tmpfs]$ cat -n plop | sed -n 'h;:z;/%/{s/\(%[^%]*%\)//1;tz;g;p}'
     2  cou%cou
     4  coucou%
     5  %cou%cou%

[tmpfs]$
Chez moi ça marche, par contre comme "%" est un caractère réservé de Windows (au même titre que "!" pour GNU/Linux), il est fort possible que ça interfère...

Désolé ;-(
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

14

eZula, le 5 avr 2009 à 23:12:53

En effet, le caractère ne s'affiche même pas dans le terminal :)

comment tu fais sous Linux pour protéger un caractère réservé ?

Répondre à eZula

15

jipicy, le 5 avr 2009 à 23:17:10

Normalement en le protégeant avec un anti-slash '\!", par contre j'ai remarqué que tu utilisais des doubles quotes autour de ton expression, essaie avec des quotes simples...

En bash ça a son importance ;-\
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

16

eZula, le 6 avr 2009 à 07:24:41

Sous windows je crois que les ' ' ne marchent pas

grep -n '.' Path.txt   | sed -n 'h;:z;/\"/{s/\(\"[\"]*\"\)//1;tz;g;p}'
sed: -e expression #1, char 1: unknown command: `''


Sans par contre c'est possible, parfois

grep -n . Path.txt   | sed -n h;:z;/\"/{s/\(\"[\"]*\"\)//1;tz;g;p}
1:"coucou"
2:cou"cou
4:coucou"
5:"couco"u"


Pour en revenir à la recherche du motif "% impair" pas trouvé de solutions, guillemets ou pas, et même en faisant passer ce caractère dans une variable rien à faire, il ne s'affiche pas

grep -n . Path.txt   | sed -n h;:z;/\[\\)//1;tz;g;p}
sed: -e expression #1, char 13: unknown command: `/'
grep: write error: Invalid argument


quoique...

grep "%" Path.txt
utryu%uio


je vais voir peut être avec findstr...

Répondre à eZula

17

jipicy, le 6 avr 2009 à 07:46:37

grep -n '.' Path.txt | sed -n 'h;:z;/\"/{s/\(\"[\"]*\"\)//1;tz;g;p}'
sed: -e expression #1, char 1: unknown command: `''


A ce moment là il ne faut pas échapper les \", essaye sans les échapper...
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

18

eZula, le 6 avr 2009 à 08:32:52

J'avais essayé comme ceci

grep -n "." Path.txt | sed -n "h;:z;/%/{s/\(%[%]*%\)//1;tz;g;p}"


et dans le shell les caractères % ne s'affichent pas d'où erreur

Répondre à eZula

19

jipicy, le 6 avr 2009 à 08:37:44

Essaie comme ça :

grep -n "." Path.txt | sed -n 'h;:z;/%/{s/\(%[%]*%\)//1;tz;g;p}'
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

20

eZula, le 6 avr 2009 à 08:47:05

>grep -n "." Path.txt | sed -n 'h;:z;/[\)//1;tz;g;p}'
sed: -e expression #1, char 1: unknown command: `''
grep: write error: Invalid argument


Edit >

>grep -n "." Path.txt | sed -n "h;:z;/[\)//1;tz;g;p}"
sed: -e expression #1, char 20: unterminated address regex


bouh :/

ça doit vraiment être ce caractère %, s'il y en a deux il doit supposer que ce qui se situe entre est une variable, et vu que ce n'est pas déclaré parcequ'elle n'existe pas, ça ne fonctionne pas.

Cet exemple avec les & marche, sans protection...

>grep -n "." Path.txt | sed -n "h;:z;/&/{s/\(&[&]*&\)//1;tz;g;p}"
8:regrg&gedr


faudrait l'empêcher d'interpréter le % c'est pas gagné. Avec d'autres séparateurs pour SED tu crois que c'est possible ?

Répondre à eZula

21

jipicy, le 6 avr 2009 à 08:56:00

Effectivement c'est l'interprétation de % par Windows qui pose problème, va te falloir attendre un expert en Windows ;-))

Quant au séparateur, ça n'a rien à voir dans la mesure où le caractère "%" n'est pas utilisé comme séparateur.
On en change quand justement il risque d'y avoir confusion et pour éviter la protection comme dans un chemin :

sed 's/\/home\/user\/chemin/blablabla/'

sed 's%/home/user/chemin%blablabla%'

là oui c'est utile, ne serait-ce que pour la visibilité ;-))
$ man woman
Il n'y a pas de page de manuel pour woman.

Répondre à jipicy

22

dubcek, le 6 avr 2009 à 09:03:52

Hello
et avec awk, disponible

awk ' /\"/ {x=$0;n=gsub("\"", "X", x);if(n % 2 ) print NR, $0 }' 

Répondre à dubcek