GREP nombre impair
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
43 réponses
La problématique consiste à détecter dans un fichier les lignes contenant un nombre impair de guillemets, dans le cadre du débogage d'un batch DOS, en privilégiant sed ou awk. Plusieurs réponses privilégient awk pour compter les guillemets et restituer les lignes dont le compte est impair, en utilisant gsub et une condition modulo. Des variantes existent, comme traiter les lignes contenant des guillemets et déterminer la parité via gsub, ou combiner sed et substitution pour évaluer la présence et l'absence des guillemets. En pratique, certains exemples affichent le numéro de ligne et son contenu lorsque le comptage est impair, tout en signalant que l'échappement des guillemets sur Windows peut compliquer l'analyse.
-
ContributeurTiens ça pourrait être très intéressant ça aussi
-
Contributeuret on peut affiner, par ex. lignes dont le champ 2 ne contient pas %
$2 !~ /%/
lignes dont le champ 3 n'est pas égal à %
$3 !~ /^%$/ -
Modérateur;-))
-
ContributeurEdition : ok comme ça
!/^\%/ {if(found==0) { print NR":"$0, " ==> Ne commence pas par %" ; found=1;} next; }
Merci :) -
ModérateurNormalement la négation s'obtient avec un "!" (point d'exclamation) :
!/^%/ { print NR, $0, " ==> Ne commence pas par %" }; next; } -
ContributeurOk ça semble marcher, merci ;)
J'ai ajouté ceci
/\"/ {print NR":"$0, "==> Guillemet" }
pour avoir à coté du n° de ligne un ":"
Juste une dernières question : pour la "négation" d'affichage de ligne ("tout sauf") il y aurait une autre possibilité que ça
/^%/ {if(found==0) { print NR, $0, " ==> Ne commence pas par %" ; found=1;} next; }
Je cherche les lignes qui ne commencent par par un % et ça donne un résultat à côté de la plaque (par exemple : 1 %SystemRoot%\inform.dat" ==> Ne commence pas par %) -
Contributeurle premier " est protégé parce ce n'est pas un séparateur mais un caractère recherché et il faut 2 " pour définir une chaine de caractères à afficher par la commande print
/\"/ {print NR, $0, "==> Guillemet" }
$ awk -f f1.awk < f1.txt
1 %SystemRoot%\)inf"orm.dat ==> Guillemet -
Contributeurnon, en fait c'est guillement tout court (protégé par un \), par exemple un résultat attendu serait
4.%SystemRoot%\infor"m.dat ==> Guillemet
résultat effectif sans protection :
awk: Outil\f1.awk:3: /"/ {print NR, $0, ==> Guillemet"} awk: Outil\f1.awk:3: ^ syntax error-
ModérateurOops j'avions pas vu que tu cherchais des guillemets, j'en étais resté aux parenthèses ;-((
Au cas ou tu voudrais revenir sur la commande "sed" (bien que je pense que dubcek devrait trouver aisément d'où vient le problème), je te mets la syntaxe avec le comptage de ligne :sed '=' fichier | sed -n 'N;s/\n/ /;/\(\|\)/ s/.*/& ==> Parenthèse/p'
-
-
Modérateur/\"/ {print NR, $0, ==> Guillemet" }
C'est quoi c'est anti-slash suivi d'un guillemet ???
Il n'en manque pas un non plus avant le "==> ???
-
Contributeurje comprends pas... plus aucune détection, plus rien ne marche, c'est horrible :))
awk: Outil\f1.awk:3: /\"/ {print NR, $0, ==> Guillemet" } awk: Outil\f1.awk:3: ^ syntax error awk: Outil\f1.awk:3: /\"/ {print NR, $0, ==> Guillemet" } awk: Outil\f1.awk:3: ^ unterminated string
avec ou sans espace avant le } pareil
sinon y'a la solution SED de jipicy qui est intéressante, mais c'est pour aller au bout des choses quand même
Et pour le NR, c'est étrange qu'il ne l'affiche pas, non ? -
Contributeurle problème c'est la ligne de commande DOS, qui exige des ", donc il faut protéger ceux du print avec \ et qui comprend > comme une redirection qu'il faut aussi protéger, mais avec ^ !!!
mais rien de tout ça dans un fichier de commande awk :
/\(|\)/ {print $0, "==> Parenthèse"} -
ContributeurTrès bien, merci pour ces solutions :)
j'aimerais retenir awk car justement j'ai déjà le fichier f1.awk http://www.commentcamarche.net/forum/affich 11856910 grep nombre impair?page=2#25
Par contre si je mets
AWK "/\(|\)/ {print $0, \"==^> Parenthèse\"}" %%G
dans le batch ça fonctionne, mais dans Outil\f1.awk, sous la première ligne
/\&/ {x=$0;n=gsub("&", "X", x);if(n % 2 ) print NR, $0 } /\(|\)/ {print $0, \"==^> Parenthèse\"}
avec bien sur AWK -f Outil\f1.awk %%G pour le lancer ça ne marche pas :
awk: Outil\f1.awk:2: /\(|\)/ {print NR, $0, \"==> Parenthèse\"} awk: Outil\f1.awk:2: ^ backslash not last character on line
PS : j'ai ajouté NR car je voudrais qu'il me mette le résultat de la même manière que grep :
1.ligne ==> argument
même ça ça marche pas :(
j'aimerais faire pareil avec les guillemets
/\"/ {print NR, $0, \"==> Guillemet\"} -
ModérateurAvec "sed" ;-))
sed -n "/\(\|\)/ s/.*/& ==> Parenthèse/p" fichier %SystemRoot%\)inform.dat ==> Parenthèse %SystemRoot%\(nvchost.exe ==> Parenthèse
-
Contributeuren ligne de commande en DOS
$ awk "/\(|\)/ {print $0, \"==^> Parenthèse\"}" f1.txt
%SystemRoot%\)inform.dat ==> ParenthÞse
%SystemRoot%\(nvchost.exe ==> ParenthÞse -
Contributeursalut,
tu as raison, je viens de réaliser qu'il n'affiche cet echo qu'une fois toutes les lignes testées,
je vais voir autrement, merci -
Contributeurhello
parce que le echo ne s'exécute qu'une fois et après la dernière ligne, il faut plutôt utiliser sed ou awk -
ContributeurSalut,
je suis tjs sur ce débogage et je rencontre un problème de logique avec cette condition :
Outil\GREP -nE "(\(|\))" %%G &&ECHO ==^> Parenthèse
sur mon fichier test j'ai deux lignes trafiquées comme suivant :
%SystemRoot%\)inform.dat %SystemRoot%\(nvchost.exe
et voilà la délation du débogueur :
3:%SystemRoot%\)inform.dat 4:%SystemRoot%\(nvchost.exe ==> Parenthèse
vous constatez comme moi que ==> Parenthèse n'apparait que sur la ligne où se trouve le 1er motif de grep càd la parenthèse ouverte ( ; bien entendu je souhaiterais que ça apparaisse pour chaque motif.
Je suis sur que je vous embête à poser mes questions windows dans ce forum mais est-ce que ce problème incombe à grep d'après vous : sous Linux ça donnerait quoi svp ?
Merci -
ContributeurOK ça roule. Je précise juste que sous windows (bien obligé de faire avec :( ) - et en tout cas avec awk.exe et gawk.exe - ça fonctionne sous condition de protéger les guillemets du séparateur
echo cmire | awk "BEGIN {FS=\"\"} {print $2$5$4$1$3}"
sinon c'est
awk: BEGIN {FS="} awk: ^ unterminated string Le processus a tenté d'écrire sur un canal inexistant.
Merci encore et à ++ -
Contributeurle séparateur peut-être n'importe quelle expression régulière ou un/des mots. Dans ton exemple, il faut spécifier qu'il n'y a pas de séparateur ou plutôt que le séparateur est "rien"
$ echo cmire | awk 'BEGIN {FS=""} {print $2$5$4$1$3}'
merci -
Contributeur
echo cmire | awk 'BEGIN {FS="c"} {print $2$5$4$1$3}'
je m'entraine :)
Tiens, juste un dernier truc, et par rapport à cette dernière commande (censée afficher "merci"). Est-il possible de définir le séparateur "caractère alphabétique" par exemple pour ordonner une expression toute simple ? j'ai essayé [a-z] mais il n'en veut pas, j'ai donc du partir sur la première lettre de l'expression.
Promis c'est la dernière question ;)
- 1
- 2
- 3