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 31/05/2017, à 10:48

Tangram

[RESOLU] find+exec+sh+grep : retour de grep invariable

Salut à tous,

J'ai un problème avec ce script shell :

#!/bin/sh
#
find . -name "texte.txt" \
   -exec sh -c "mv {} _tmpfile;
                grep -q $'\r' _tmpfile;
                echo $?" \;


grep est supposé retourner une valeur différente s'il trouve des CR ou pas. Or la valeur retournée est toujours la même, que le texte contienne des CR ou non. Une idée ?

PS: mon intention est bien sûr de parcourir un répertoire récursivement, c'est la raison pour laquelle je présente le script sous cette formulation.

Dernière modification par Tangram (Le 31/05/2017, à 16:08)

#2 Le 31/05/2017, à 11:06

Postmortem

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Salut,
Je pense qu'il suffit de rajouter un « \ » sur la dernière ligne :
echo \$?" \;

Edit:
Ah non, ça suffit pas, "sh" ne semble pas savoir traduire $'\r', il faudrait :

find . -name "texte.txt" -exec bash -c "grep -q $'\r' \$0; echo \$?" '{}' \;

Ou pour repartir sur ce que tu as fait :

find . -name "texte.txt"    -exec bash -c "mv {} _tmpfile;
                grep -q $'\r' _tmpfile;
                echo \$?" \;

Dernière modification par Postmortem (Le 31/05/2017, à 11:19)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#3 Le 31/05/2017, à 11:19

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Postmortem a écrit :

Edit:
Ah non, ça suffit pas, "sh" ne semble pas savoir traduire $'\r', il faudrait :

find . -name "texte.txt" -exec bash -c "grep -q $'\r' \$0; echo \$?" '{}' \;

Effectivement, là ça réagit correctement. J'aurais pourtant aimé rester en 'sh'. Impossible ?

#4 Le 31/05/2017, à 11:23

Postmortem

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

find . -name "texte.txt"    -exec sh -c "mv {} _tmpfile;
                grep -q '^M' _tmpfile;
                echo \$?" \;

Le « ^M » se tape en faisant « Ctrl-v » puis « Ctrl-m ».


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#5 Le 31/05/2017, à 12:34

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Postmortem a écrit :
find . -name "texte.txt"    -exec sh -c "mv {} _tmpfile;
                grep -q '^M' _tmpfile;
                echo \$?" \;

Le « ^M » se tape en faisant « Ctrl-v » puis « Ctrl-m ».

Ça fonctionne parfaitement pour une ligne de commande, mais pas pour un script.
Avec '[[:cntrl:]]', le script réagit bien par contre, mais '[[:cntrl:]]' est trop généraliste...

#6 Le 31/05/2017, à 12:47

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

"grep -q \$(echo -e '\r') _tmpfile;" semble fonctionner correctement. Des réserves (compatibilité, notamment) ?

Dernière modification par Tangram (Le 31/05/2017, à 13:05)

#7 Le 31/05/2017, à 14:00

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

"grep -q `echo \\\r` _tmpfile;" est plus compatible, non ? En tout cas, il fonctionne aussi.

#8 Le 31/05/2017, à 15:38

Postmortem

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Tangram a écrit :

"grep -q `echo \\\r` _tmpfile;" est plus compatible, non ? En tout cas, il fonctionne aussi.

Perso, j'utiliserais la syntaxe « $(commande) » plutôt que « `commande` ».

Pour le « echo » en lui-même, je ne sais pas... Est ce que tous les « sh » embarquent une version interne de « echo » qui acceptent les options « -e » et « -E » ? Et s'il n'y a pas de version interne de « echo », est ce que le binaire accepte toujours les options « -e » et « -E » ?
Et dans tous les cas, est-ce le comportement « -e » ou « -E » qui est par défaut ?

Bref, perso je fais pas de « sh » car selon la distribution linux ou le système Unix, il y a des différences.
Il y a des distribs Linux où « sh » est un lien vers « dash » ; d'autres, c'est un lien vers « bash ».
Sur les systèmes Unix, selon le système, il y a des différences.

Au moins « bash », quand il est installé, c'est le même (à la version prêt bien sûr).

Dernière modification par Postmortem (Le 31/05/2017, à 15:44)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#9 Le 31/05/2017, à 16:07

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Ok. Bon on va dire que c'est résolu ;-)

#10 Le 02/06/2017, à 07:56

Postmortem

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Salut,
J'ai pas essayé mais je me demandais si simplement ceci fonctionnait :

find . -name "texte.txt" -exec sh -c 'mv {} _tmpfile; grep -q "\\r" _tmpfile; echo $?' \;

Edit :
Ah non, la commande ci-dessus ne fonctionne pas !

Dernière modification par Postmortem (Le 02/06/2017, à 09:38)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#11 Le 02/06/2017, à 11:40

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Pour la compatibilité, il est toujours possible de recourir à 'printf' :

find . -name "texte.txt" -exec sh -c 'mv {} _tmpfile; grep -q $(printf "\r") _tmpfile; printf "%d\n" $?' \;

#12 Le 02/06/2017, à 12:10

Postmortem

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Le souci, c'est que si je me souviens bien, il y avait certains sh qui transformaient « "\r" » en « r » avant l'exécution de la commande ; « printf "\r" » afficherait donc « r ».
J'ai testé avec dash (sh est un lien vers dash sur mon PC) et bash (sur un serveur, sh est un lien vers bash mais ça exécute bash « en version sh ») et « "\r" » est bien transformé en « \r » avant exécution, donc c'est bon.

Mais pour être certain, le mieux serait de mettre « printf '\r' » (des simples quotes au lieu des doubles), tu seras ainsi certain que ça restera « \r ».


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#13 Le 02/06/2017, à 12:30

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Ok. Mais si les double-quotes sont rétablies, il faut rétablir aussi le backslash devant le '$?' du dernier printf :

find . -name "texte.txt" -exec sh -c "mv {} _tmpfile; grep -q $(printf '\r') _tmpfile; printf '%d\n' \$?" \;

J'avais converti mon programme en bash, mais je pense qu'avec ça, je vais pouvoir le restaurer en sh...

#14 Le 02/06/2017, à 17:16

Postmortem

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

En fait, pour qu'il n'y ait aucune interprétation avant l'exécution, il faudrait faire :

find . -name "texte.txt" -exec sh -c 'mv {} _tmpfile; grep -q $(printf '\'\\r\'') _tmpfile; printf '\''%d\n'\'' $?' \;

Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#15 Le 02/06/2017, à 23:26

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable

Et maintenant, le moment de la révélation : j'ai donc créé, avec l'aide de Postmortem, trois petits scripts qui permettent de changer indifféremment les retours de ligne de mes sources entre Macintosh (les vieux), MS-DOS/Windows et Unix, quelque soit le fichier de départ. Ces programmes fonctionnent très bien sur Ubuntu. Ceci dit, j'émettrai des réserves quant à leur efficacité sur les autres systèmes d'exploitation. La ligne du 'sed' dans todos.sh me chagrine un peu, il se peut que le signe de fin de ligne '$' soit interprété différemment d'un OS à l'autre. Donc, si ça intéresse quelqu'un, faites des tests préalables, que je ne sois pas responsable d'un irréparable chamboulement de vos fichiers texte.

todos.sh:

#!/bin/sh
#
# todos.sh :
# Convert files from Unix (LF) or Macintosh (CR) to Windows/MS-DOS (CRLF)

find . -type f '(' \
   -name '*.c' -o \
   -name '*.h' -o \
   -name 'makefile.*' -o \
   -name '*.txt' -o \
   -name '*.bat' -o \
   -name '*.BAT'\
   ')' \
   -exec sh -c 'printf '\'\\r%s%15s\\r\'' {} '\'\'';
                grep -q $(printf '\'\\r\'') {};
                if [ $? -eq 0 ];
                then
                    mv {} _tmpfile;
                    tr -d '\'\\n\'' < _tmpfile > _tmpfile2;
                    tr '\'\\r\'' '\'\\n\'' < _tmpfile2 > {};
                    touch -r _tmpfile {};
                    rm _tmpfile2;
                    rm _tmpfile;
                fi;
                mv {} _tmpfile;
                sed '\'s/\$/\\r/\'' _tmpfile > {};
                touch -r _tmpfile {};
                rm _tmpfile' \;
echo

tomac.sh :

#!/bin/sh
#
# tomac.sh :
# Convert files from Unix (LF) or Windows/MS-DOS (CRLF) to Macintosh (CR)

find . -type f '(' \
   -name '*.c' -o \
   -name '*.h' -o \
   -name 'makefile.*' -o \
   -name '*.txt' -o \
   -name '*.bat' -o \
   -name '*.BAT' \
   ')' \
   -exec sh -c 'mv {} _tmpfile;
                printf '\'\\r%s%15s\\r\'' {} '\'\'';
                grep -q $(printf '\'\\r\'') _tmpfile;
                if [ $? -eq 0 ];
                then
                    tr -d '\'\\n\'' < _tmpfile > {};
                else
                    tr '\'\\n\'' '\'\\r\'' < _tmpfile > {};
                fi;
                touch -r _tmpfile {};
                rm _tmpfile' \;
echo

tounix.sh :

#!/bin/sh
#
# tounix.sh :
# Convert files from Windows/MS-DOS (CRLF) or Macintosh (CR) to Unix (LF)

find . -type f '(' \
   -name '*.c' -o \
   -name '*.h' -o \
   -name 'makefile.*' -o \
   -name '*.txt' -o \
   -name '*.bat' -o \
   -name '*.BAT' \
   ')' \
   -exec sh -c 'printf '\'\\r%s%15s\\r\'' {} '\'\'';
                grep -q $(printf '\'\\r\'') {};
                if [ $? -eq 0 ];
                then
                    mv {} _tmpfile;
                    tr -d '\'\\n\'' < _tmpfile > _tmpfile2;
                    tr '\'\\r\'' '\'\\n\'' < _tmpfile2 > {};
                    touch -r _tmpfile {};
                    rm _tmpfile2;
                    rm _tmpfile;
                fi' \;
echo

Dernière modification par Tangram (Le 02/06/2017, à 23:57)

#16 Le 03/06/2017, à 09:35

Tangram

Re : [RESOLU] find+exec+sh+grep : retour de grep invariable