Pour migrer des fonctions regex en fonctions pcre automatiquement.
Le
Jean-Francois Ortolo
Bonjour
J'ai l'honneur ( excusez du peu ;) ) de présenter une solution de
migration semi automatique, des fonctions de type regex: split(),
ereg(), eregi(), ereg_replace(), et eregi_replace(), vers leurs
équivalents de type pcre : preg_split(), preg_match(), et preg_replace().
En effet, ces fonctiosn regex, disparaîtront à la version PHP 6, et
il est donc souhaitable de pouvoir migrer ses sites vers les nouvelles
fonctions.
Compte tenu du fait que celà intéresse avant tout les programmeurs
php, j'espère que le modérateur va laisser passer ce message, bien que
ses outils relèvent plutôt de la programmation Shell et Awk. ;(
Cette solution se compose d'un script en Bourne Shell migration.sh, à
placer dans la racine du site web à migrer, et d'un script awk
filtre.awk à placer aussi dans la racine du site à migrer.
Voici le code des ces deux scripts :
D'abord, migration.sh
La variable dir_init doit être alimentée avec le répertoire dans
lequel est installé ce script ( répertoire racine du site web ).
Ce script est censé être lancé à partir du compte root.
La variable perm doit être alimentée avec le propriétaire et groupe
des scripts php à migrer.
Excusez-moi du fait que ces instructions sont sous forme de
citations, j'ai la flemme d'enlever manuellement les débuts de lignes.
> #!/bin/sh
>
> # Propriétaire et groupe
> # des scripts *.php
> perm="root:root"
>
> # Variables de configuration, c'est le répertoire de départ.
> dir_init="/var/www/html/php"
>
> # Et le script awk de filtre.
> filtre_awk=${dir_init}"/filtre.awk"
>
> # On calcule le répertoire absolu courant.
> # Quand le paramètre n'est pas présent,
> # c'est le répertoire de départ, sinon
> # c'est le paramètre du script.
> if [ $# -eq 0 ]; then
> dir=${dir_init}
> else
> dir=$1
> fi
>
> # Positionnement dans le répertoire courant.
> cd ${dir}
>
> # On parcourt le répertoire courant en sélectionnant
> # tous les scripts php.
> for i in `ls *.php 2>/dev/null`; do
> if [ -f $i ]; then
> file=${dir}"/"${i}
> file2=${dir}"/super_new_"${i}".txt"
>
> # Traitement du script *.php,
> # là on se contente d'afficher son nom
> # avec son chemin absolu.
> #
> echo ${file} > /root/tmp2.txt
> echo ${file2} >> /root/tmp2.txt
> echo "" >> /root/tmp2.txt
>
> awk -f ${filtre_awk} -- ${file} 1>${file2} 2>>/root/tmp2.txt
>
> chown $perm ${file2}
> chmod 777 ${file2}
>
> t1=`ls -l ${file} | awk '{ print $5; }'`
> t2=`ls -l ${file2} | awk '{ print $5; }'`
>
> if [ ${t1} -ne ${t2} ]; then
> cat /root/tmp2.txt >> /root/tmp.txt
> fi
> fi
> done
>
> # On lit tous les sous-répertoires du répertoire courant,
> # et on relance le même script, avec ces sous-répertoires
> # comme paramètre, pour que ces processus fils
> # se positionnent sur ces sous-répertoires.
> #
> for j in `ls -d * 2>/dev/null`; do
> if [ -d $j ]; then
>
> # Calcul du sous-répertoire absolu.
> direct=${dir}"/"${j}
>
> ${dir_init}/migration.sh ${direct}
> fi
> done
>
> # A la fin du script, on remonte vers le répertoire
> # père.
> cd ..
>
> exit 0
Ensuite, voici le code du script filtre.awk :
> function change(param)
> {
> p=split(param, tableau, "");
>
> drapeau=0;
> n=0;
>
> for(i=1; i<=p; i++)
> {
> t=tableau[i];
>
> if(drapeau!=0)
> {
> if(n==0)
> {
> if(t=="\\")
> {
> n++;
> }
> else
> {
> if(t==s)
> {
> chaine=chaine "/" s;
> break;
> }
> else
> chaine=chaine t;
> }
> }
> else
> {
> if(t=="\\")
> n++;
> else
> {
> d="";
> for(k=1; k<=n; k++)
> d=d "\\";
>
> chaine=chaine d;
>
> q=n;
> if(((2*int(q/2.0))==n)&&(t==s))
> {
> chaine=chaine "/" s;
> break;
> }
> else
> chaine=chaine t;
>
> n=0;
> }
> }
>
> }
> else
> {
> if((t=="'")||(t=="\""))
> {
> drapeau=1;
> s=t;
> chaine=t "/";
> }
> # Début de chr(nombre)
> # ou de variable masque.
> else if((t=="c")||(t=="$"))
> {
> chaine=t;
> break;
> }
> }
> }
>
> i++;
>
> for(; i<=p; i++)
> {
> t=tableau[i];
> chaine=chaine t;
> }
>
> return(chaine);
> }
> function change_i(param)
> {
> p=split(param, tableau, "");
>
> drapeau=0;
> n=0;
>
> for(i=1; i<=p; i++)
> {
> t=tableau[i];
>
> if(drapeau!=0)
> {
> if(n==0)
> {
> if(t=="\\")
> {
> n++;
> }
> else
> {
> if(t==s)
> {
> chaine=chaine "/i" s;
> break;
> }
> else
> chaine=chaine t;
> }
> }
> else
> {
> if(t=="\\")
> n++;
> else
> {
> d="";
> for(k=1; k<=n; k++)
> d=d "\\";
>
> chaine=chaine d;
>
> q=n;
> if(((2*int(q/2.0))==n)&&(t==s))
> {
> chaine=chaine "/i" s;
> break;
> }
> else
> chaine=chaine t;
>
> n=0;
> }
> }
>
> }
> else
> {
> if((t=="'")||(t=="\""))
> {
> drapeau=1;
> s=t;
> chaine=t "/";
> }
> # Début de chr(nombre)
> # ou de variable masque.
> else if((t=="c")||(t=="$"))
> {
> chaine=t;
> break;
> }
> }
> }
>
> i++;
>
> for(; i<=p; i++)
> {
> t=tableau[i];
> chaine=chaine t;
> }
>
> return(chaine);
> }
> {
> line=$0;
> line2=$0;
>
> if(line ~ /=[ \t]*split[ ]*\(/)
> {
> r=split(line, tableau, /=[ \t]*split[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "= preg_split(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /eregi[ ]*\(/)
> {
> split(line, tableau, /eregi[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_match(";
> v=change_i(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /ereg[ ]*\(/)
> {
> split(line, tableau, /ereg[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_match(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /eregi_replace[ ]*\(/)
> {
> split(line, tableau, /eregi_replace[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_replace(";
> v=change_i(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /ereg_replace[ ]*\(/)
> {
> split(line, tableau, /ereg_replace[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_replace(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> printf ("%s", line);
>
> if(line!=line2)
> {
> print "D'abord:" line2 " Ensuite:" line > "/dev/stderr"
> }
> }
A la fin de la migration, vous avez le fichier de logs /root/tmp.txt
qui contient les chemins absolus des scripts php avant et après
migration, ainsi que les lignes des fonctions migrées.
Ce fichier ne contient que les scripts modifiés, pas les scripts
inchangés.
Pour arranger le formattage, je suggère de séparer ce fichier de
logs, en deux fichiers indexé de 1 à n, n étant le nombre de fichiers
modifiés.
Pour celà :
cat tmp.txt | awk 'BEGIN{ i=0; j=0; }{ if(length($0)<5) { i++; j++;
if(j==1) print i; } else if ($0 !~ /Ensuite/) { j=0; print $0; } }' >
fichiers.txt
cat tmp.txt | awk 'BEGIN{ i=0; j=0; }{ if(length($0)<5) { i++; j++;
if(j==1) print i; } else if ($0 ~ /Ensuite/) { j=0; print $0; } }' | awk
'{ for(i=2; i<=NF; i++) if($i != "Ensuite:") printf("%s ", $i); else
printf(" "); printf(""); }' > fonctions.txt
Ensuite, vous aurez dans fichiers.txt la liste indexés de 1 à n des
chemins absolus des fichiers sources et cibles par paires, et dans
fonctions.txt la liste indexée des fonctions avant et après migration,
par groupes de fonctions pour chaque fichiers modifiés.
Dans les deux cas, l'index va de 1 à n, et n a la même valeur dans
les deux cas.
Il faut obligatoirement vérifier dans le fichier fonctions.txt qu'il
n'y a pas d'erreur lors de la migration des fonctions.
Théoriquement la seule erreur peut résulter du fait que l'expression
rationnelle est contenue dans une variable php ( commençant par $ le
caractère dollar ). Dans ce cas évidemment, il n'y a pas d'autre
solution que d'éditer manuellement le fichier cible correspondant ( de
même index dans le fichiers fichiers.txt ), pour modifier cette variable
php qui sert d'expression rationnelle.
Comme conclusion, je serais intéressé à ce que vous m'indiquiez les
erreurs de programmation éventuelles que vous voyez, car je suis en
train de faire cette migration sur mon ordinateur, pour mon site
www.pronostics-courses.fr versions locale et remote, ainsi que pour le
site www.lescourses.com, mon site partenaire, que j'ai copié sur mon
ordinateur. ;) Celà me permettrait de diminuer le risque d'erreurs.
Je suis aussi intéressé par vos remarques et suggestions, compte tenu
du fait que cette topique de migration automatisée de fonctions regex
vers des fonctions pcre, avait été abordée il y de celà quelques
semaines ou mois.
Bien à vous.
Amicalement.
Jean-François Ortolo
--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.
Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
J'ai l'honneur ( excusez du peu ;) ) de présenter une solution de
migration semi automatique, des fonctions de type regex: split(),
ereg(), eregi(), ereg_replace(), et eregi_replace(), vers leurs
équivalents de type pcre : preg_split(), preg_match(), et preg_replace().
En effet, ces fonctiosn regex, disparaîtront à la version PHP 6, et
il est donc souhaitable de pouvoir migrer ses sites vers les nouvelles
fonctions.
Compte tenu du fait que celà intéresse avant tout les programmeurs
php, j'espère que le modérateur va laisser passer ce message, bien que
ses outils relèvent plutôt de la programmation Shell et Awk. ;(
Cette solution se compose d'un script en Bourne Shell migration.sh, à
placer dans la racine du site web à migrer, et d'un script awk
filtre.awk à placer aussi dans la racine du site à migrer.
Voici le code des ces deux scripts :
D'abord, migration.sh
La variable dir_init doit être alimentée avec le répertoire dans
lequel est installé ce script ( répertoire racine du site web ).
Ce script est censé être lancé à partir du compte root.
La variable perm doit être alimentée avec le propriétaire et groupe
des scripts php à migrer.
Excusez-moi du fait que ces instructions sont sous forme de
citations, j'ai la flemme d'enlever manuellement les débuts de lignes.
> #!/bin/sh
>
> # Propriétaire et groupe
> # des scripts *.php
> perm="root:root"
>
> # Variables de configuration, c'est le répertoire de départ.
> dir_init="/var/www/html/php"
>
> # Et le script awk de filtre.
> filtre_awk=${dir_init}"/filtre.awk"
>
> # On calcule le répertoire absolu courant.
> # Quand le paramètre n'est pas présent,
> # c'est le répertoire de départ, sinon
> # c'est le paramètre du script.
> if [ $# -eq 0 ]; then
> dir=${dir_init}
> else
> dir=$1
> fi
>
> # Positionnement dans le répertoire courant.
> cd ${dir}
>
> # On parcourt le répertoire courant en sélectionnant
> # tous les scripts php.
> for i in `ls *.php 2>/dev/null`; do
> if [ -f $i ]; then
> file=${dir}"/"${i}
> file2=${dir}"/super_new_"${i}".txt"
>
> # Traitement du script *.php,
> # là on se contente d'afficher son nom
> # avec son chemin absolu.
> #
> echo ${file} > /root/tmp2.txt
> echo ${file2} >> /root/tmp2.txt
> echo "" >> /root/tmp2.txt
>
> awk -f ${filtre_awk} -- ${file} 1>${file2} 2>>/root/tmp2.txt
>
> chown $perm ${file2}
> chmod 777 ${file2}
>
> t1=`ls -l ${file} | awk '{ print $5; }'`
> t2=`ls -l ${file2} | awk '{ print $5; }'`
>
> if [ ${t1} -ne ${t2} ]; then
> cat /root/tmp2.txt >> /root/tmp.txt
> fi
> fi
> done
>
> # On lit tous les sous-répertoires du répertoire courant,
> # et on relance le même script, avec ces sous-répertoires
> # comme paramètre, pour que ces processus fils
> # se positionnent sur ces sous-répertoires.
> #
> for j in `ls -d * 2>/dev/null`; do
> if [ -d $j ]; then
>
> # Calcul du sous-répertoire absolu.
> direct=${dir}"/"${j}
>
> ${dir_init}/migration.sh ${direct}
> fi
> done
>
> # A la fin du script, on remonte vers le répertoire
> # père.
> cd ..
>
> exit 0
Ensuite, voici le code du script filtre.awk :
> function change(param)
> {
> p=split(param, tableau, "");
>
> drapeau=0;
> n=0;
>
> for(i=1; i<=p; i++)
> {
> t=tableau[i];
>
> if(drapeau!=0)
> {
> if(n==0)
> {
> if(t=="\\")
> {
> n++;
> }
> else
> {
> if(t==s)
> {
> chaine=chaine "/" s;
> break;
> }
> else
> chaine=chaine t;
> }
> }
> else
> {
> if(t=="\\")
> n++;
> else
> {
> d="";
> for(k=1; k<=n; k++)
> d=d "\\";
>
> chaine=chaine d;
>
> q=n;
> if(((2*int(q/2.0))==n)&&(t==s))
> {
> chaine=chaine "/" s;
> break;
> }
> else
> chaine=chaine t;
>
> n=0;
> }
> }
>
> }
> else
> {
> if((t=="'")||(t=="\""))
> {
> drapeau=1;
> s=t;
> chaine=t "/";
> }
> # Début de chr(nombre)
> # ou de variable masque.
> else if((t=="c")||(t=="$"))
> {
> chaine=t;
> break;
> }
> }
> }
>
> i++;
>
> for(; i<=p; i++)
> {
> t=tableau[i];
> chaine=chaine t;
> }
>
> return(chaine);
> }
> function change_i(param)
> {
> p=split(param, tableau, "");
>
> drapeau=0;
> n=0;
>
> for(i=1; i<=p; i++)
> {
> t=tableau[i];
>
> if(drapeau!=0)
> {
> if(n==0)
> {
> if(t=="\\")
> {
> n++;
> }
> else
> {
> if(t==s)
> {
> chaine=chaine "/i" s;
> break;
> }
> else
> chaine=chaine t;
> }
> }
> else
> {
> if(t=="\\")
> n++;
> else
> {
> d="";
> for(k=1; k<=n; k++)
> d=d "\\";
>
> chaine=chaine d;
>
> q=n;
> if(((2*int(q/2.0))==n)&&(t==s))
> {
> chaine=chaine "/i" s;
> break;
> }
> else
> chaine=chaine t;
>
> n=0;
> }
> }
>
> }
> else
> {
> if((t=="'")||(t=="\""))
> {
> drapeau=1;
> s=t;
> chaine=t "/";
> }
> # Début de chr(nombre)
> # ou de variable masque.
> else if((t=="c")||(t=="$"))
> {
> chaine=t;
> break;
> }
> }
> }
>
> i++;
>
> for(; i<=p; i++)
> {
> t=tableau[i];
> chaine=chaine t;
> }
>
> return(chaine);
> }
> {
> line=$0;
> line2=$0;
>
> if(line ~ /=[ \t]*split[ ]*\(/)
> {
> r=split(line, tableau, /=[ \t]*split[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "= preg_split(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /eregi[ ]*\(/)
> {
> split(line, tableau, /eregi[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_match(";
> v=change_i(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /ereg[ ]*\(/)
> {
> split(line, tableau, /ereg[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_match(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /eregi_replace[ ]*\(/)
> {
> split(line, tableau, /eregi_replace[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_replace(";
> v=change_i(u);
> line=line v;
> }
> }
> }
>
> if(line ~ /ereg_replace[ ]*\(/)
> {
> split(line, tableau, /ereg_replace[ ]*\(/);
>
> for(l=1; l<=r; l++)
> {
> u=tableau[l];
>
> if(l==1)
> line=u;
> else
> {
> line=line "preg_replace(";
> v=change(u);
> line=line v;
> }
> }
> }
>
> printf ("%s", line);
>
> if(line!=line2)
> {
> print "D'abord:" line2 " Ensuite:" line > "/dev/stderr"
> }
> }
A la fin de la migration, vous avez le fichier de logs /root/tmp.txt
qui contient les chemins absolus des scripts php avant et après
migration, ainsi que les lignes des fonctions migrées.
Ce fichier ne contient que les scripts modifiés, pas les scripts
inchangés.
Pour arranger le formattage, je suggère de séparer ce fichier de
logs, en deux fichiers indexé de 1 à n, n étant le nombre de fichiers
modifiés.
Pour celà :
cat tmp.txt | awk 'BEGIN{ i=0; j=0; }{ if(length($0)<5) { i++; j++;
if(j==1) print i; } else if ($0 !~ /Ensuite/) { j=0; print $0; } }' >
fichiers.txt
cat tmp.txt | awk 'BEGIN{ i=0; j=0; }{ if(length($0)<5) { i++; j++;
if(j==1) print i; } else if ($0 ~ /Ensuite/) { j=0; print $0; } }' | awk
'{ for(i=2; i<=NF; i++) if($i != "Ensuite:") printf("%s ", $i); else
printf(" "); printf(""); }' > fonctions.txt
Ensuite, vous aurez dans fichiers.txt la liste indexés de 1 à n des
chemins absolus des fichiers sources et cibles par paires, et dans
fonctions.txt la liste indexée des fonctions avant et après migration,
par groupes de fonctions pour chaque fichiers modifiés.
Dans les deux cas, l'index va de 1 à n, et n a la même valeur dans
les deux cas.
Il faut obligatoirement vérifier dans le fichier fonctions.txt qu'il
n'y a pas d'erreur lors de la migration des fonctions.
Théoriquement la seule erreur peut résulter du fait que l'expression
rationnelle est contenue dans une variable php ( commençant par $ le
caractère dollar ). Dans ce cas évidemment, il n'y a pas d'autre
solution que d'éditer manuellement le fichier cible correspondant ( de
même index dans le fichiers fichiers.txt ), pour modifier cette variable
php qui sert d'expression rationnelle.
Comme conclusion, je serais intéressé à ce que vous m'indiquiez les
erreurs de programmation éventuelles que vous voyez, car je suis en
train de faire cette migration sur mon ordinateur, pour mon site
www.pronostics-courses.fr versions locale et remote, ainsi que pour le
site www.lescourses.com, mon site partenaire, que j'ai copié sur mon
ordinateur. ;) Celà me permettrait de diminuer le risque d'erreurs.
Je suis aussi intéressé par vos remarques et suggestions, compte tenu
du fait que cette topique de migration automatisée de fonctions regex
vers des fonctions pcre, avait été abordée il y de celà quelques
semaines ou mois.
Bien à vous.
Amicalement.
Jean-François Ortolo
--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.
Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.

Poser une question


Je vous prie de bien vouloir m'excuser, ma solution ne fonctionne que
si les scripts php sont codés en mode iso-8859-1 ou iso-8859-15, à
l'exclusion du mode utf8. Donc, en mode ascii étendu ( caractères de 0 à
255 ).
J'accepte avec plaisir et reconnaissance toutes les remarques et
critiques.
Bien à vous.
Amicalement.
Jean-François Ortolo
--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.
Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Le 07/01/2010 18:36, Jean-Francois Ortolo a écrit :
Excellent ! Je n'aurais moi-même pas eu le courage de me lancer dans
une telle entreprise. Merci aussi de venir nous en faire profiter.
Je suis d'accord avec ça. Néanmoins, je me permets de copier ma réponse
dans fr.comp.lang.regexp car cela pourrait en intéresser d'autres. Le
suivi est positionné sur fr.comp.lang.php malgré tout.
Je suis volontaire pour regarder. Pour optimiser cette relecture, est-ce
que tu pourrais commencer par epliciter un peu les limites que tu t'es
fixées ?
Par exemple :
- comment reconnais-tu un fichier PHP (extension du fichier ou présence
de - supportes-tu la syntaxe - la fonction à traduire peut-elle s'étendre sur plusieurs lignes ?
- quels délimiteurs reconnais-tu pour les chaînes (guillemets simples,
guillemets doubles, HEREDOC, NOWDOC) ?
- une regexp peut-elle être scindée en plusieurs chaînes concaténées
avec l'opérateur « . » ?
- si oui, peut-on avoir un mélange de délimiteurs ('abc' . "def") ?
- en gros, quelles sont les transformations faites à la regexp ?
Cordialement,
--
Olivier Miakinen
Bonjour Monsieur
Une remarque de mise au point pour mes scripts.
D'abord, pour le script migration.sh, il faut que l'instruction echo
"" > /root/tmp2.txt soit située avant et non pas après les deux lignes
echo ${file} >> /root/tmp2.txt et echo ${file2} >> /root/tmp2.txt ( >>
dans les deux cas, et non pas > ).
Celà permet de n'avoir qu'un seule ligne vide avant chaque groupes de
noms de fichiers suivis par les fonctions contenues dans ces fichiers.
Et puis, j'apporte un changement au traitement pour arranger le
fichier de logs :
Pour les fonctions, indexées par groupes pour chaque fichiers traités :
awk 'BEGIN { i=0; j=0; }{ if(length($0)<6) { i++; j++; if(j==1) print
i; } else if($0 ~ /Ensuite/) { j=0; q=split($0, tableau, ""); line="";
for(i=9; i<=q; i++) line=line tableau[i]; printf("%sn", line); } }'
/root/tmp.txt | awk '{ split($0, tableau, "Ensuite:"); line=tableau[1] "
" tableau[2]; printf("%sn", line); }' > fonctions.txt
Pour les fichiers, indexés par fichiers traités :
awk 'BEGIN { i=0; j=0; }{ if(length($0)<6) { i++; j++; if(j==1) print
i; } else if($0 !~ /Ensuite/) { j=0; print $0; } }' /root/tmp.txt >
fichiers.txt
Pour finir, j'ai commis une erreur ( un lapsus ), en oubliant
d'affecter la variable r à partir de tous les split à la fin du script
filtre.awk
Par exemple, pour la fonction ereg() :
r=split($0, tableau2, /ereg[ ]*(/);
au lieu de :
split($0, tableau, /ereg[ ]*(/);
En effet, il faut bien avoir le nombre des élément de l'array
tableau2. L'erreur faisait que la valeur précédente de r était prise, ce
qui occasionnait des erreurs.
Il vaut mieux je crois, mettre tableau2 systématiquement au lieu de
tableau pour le corps principal du script, car les fonctions utilisent
tableau, et je ne sais pas très bien comment fonctionnent les variables
locales aux fonctions, si elles sont réellement indépendantes des
variables externes aux fonctions. La honte... ;(
Voilà donc toutes ces erreurs corrigées.
Pour répondre à votre question, je reconnais un script php uniquement
à son extension *.php
Si la nécessité se fait jour d'identifier les scripts php d'une autre
manière, normalement ce sera le rôle du script migration.sh de le faire,
probablement d'après le contenu de ces fichiers, qui peut être lu est
interprété avec un cat.
Le problème pourrait éventuellement se poser pour des scripts php
sasn extension *.php , destinés exclusivement à être inclus dans
d'autres scripts php. J'aurai à faire cette vérification pour mon site
partenaire que j'ai copié sur mon ordinateur.
A part çà, effectivement le script filtre.awk suppose que l'expression
rationnelle source Posix, est une chaîne entourée de doubles quotes ou
de simples quotes, ou bien un caractère du type chr(nombre), ou bien une
variable php commençant par le signe dollar $
Pour traiter le cas où il pourrait y avoir plusieurs chaînes de
caractères accolées, ou bien des chaînes associées avec des variables ou
autre, il faudrait complexifier la reconnaissance de la fin de
l'expression rationnelle.
J'assume, que pour transformer une expression rationnelle Posix
simple en expression rationnelle pcre, il suffit de rajouter / avant le
début après la première quote double ou simple, et / ou /i après la fin,
avant la dernière quote double ou simple.
Cà marche avec des expressions rationnelles Posix simples, sauf
qu'évidemment quand l'expression rationnelle est sous forme de variable
php, il faut intervenir manuellement sur cette variable dans le fichier
cible, pour qu'elle devienne conforme à la norme pcre.
Dans le cas où l'expression rationnelle est dans une variable php (
détectée par le signe dollar en début d'expression ) ou est de la forme
chr(nombre), celle-ci n'est pas modiifée, mais la fonction est modifiée,
donc le fichier cible voit son nombre de caractères, augmenter.
Il n'y a donc pas de cas où un fichier source soit inchangé, bien
qu'il contienne quand même au moins une fonction à migrer. Le processus
est donc suffisamment sécurisé, pour peu que tous les scripts php
sources soient détectés.
Il faut donc, faire une vérification patiente de toutes les fonctions
migrées, ce pourquoi j'arrange le fichier de logs, vers les fichiers
fichiers.txt et fonctions.txt
fonctions.txt contient pour chaque numéro d'index ( correspondant à
un fichier source et cible dans fichiers.txt ) un groupe de lignes où
figurent à gauche la ligne du fichier avant migration, et à droite la
ligne du fichier après migration.
Il est ainsi possible, de fractionner cette vérification, en
supprimant progressivement de fonctions.txt toutes les lignes
correctement migrées, pour ne laisser que celle qui nécessitent un
traitement manuel.
Pour infos, j'ai migré sur mon ordinateur mon site web
www.pronostics-courses.fr versions locale et remote, ainsi que mon site
partenaire www.lescourses.com préalablement copié.
Globalement, j'ai mesuré que j'ai 352 fichiers migrés, et 17418
lignes migrées.
Celà signifie, que pour la vérification, j'aurai à me taper la
lecture de 17418 lignes, en regardant soigneusement les expressions
rationnelles, pour vérifier qu'il n'y a pas d'erreur.
Et encore, dans tous les cas où ces expressions rationnelles sont
contenues dans des variables php, il me faudra éditer le fichier cible
manuellement, pour modifier ces variables, en faisant attention que celà
n'entraîne pas d'effet de bord sur le reste des programmes.
Je pense honnêtement, qu'une migration entièrement automatique n'est
pas envisageable, et que ma solution n'est valable que dans le contexte
où les expressions rationnelles Posix sont simples. Enfin, il est
nécéssaire que je ne passe pas à côté de fonctions à migrer qui ne
soient pas modifiées, à cause d'erreurs imprévisibles et inapercues.
Je reconnais les limitations de mon approche.
Merci beaucoup de vos réponses.
Bien à vous.
Amicalement.
Jean-François Ortolo
--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.
Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.
Bonjour,
Ben crotte, c'est un sacré boulot mais tout est en utf-8 pour moi.
Bon, d'un autre côté, je ne dois plus avoir beaucoup d'ereg...
Bonjour Monsieur
En fait... Le problème concernerait la reconnaissance de caractères
utf-8, donc sur deux octets, ce qui dépendrait avant tout des facultés
qu'aurait awk lui-même, et le Shell bash ( ou sh ) éventuellement, à
reconnaître les caractères utf-8.
Il me semble cependant, qu'en utf-8, les caractères ascii purs sont
conservés par rapport à de l'iso-8859-1, quant aux caractères étendus (
128-255 en iso ), je ne suis pas compétent pour savoir comment ça se
traduit en utf-8.
Donc, dans l'ensemble, je ne sais pas quelles sont les conditions
pour que awk sache lire et écrire de l'utf-8, le problème de la
reconnaissance de patterns ( expressions rationnelles ) étant écarté
puisque tous les patterns utilisés dans mes deux scripts migration.sh et
filtre.awk, sont de l'ascii non étendu.
Il se peut très bien, que ma solution convienne aussi pour de
l'utf-8, mais je ne suis pas compétent pour le dire, car je suis
complètement nul en utf-8. ;)
Merci beaucoup de votre réponse.
Bien à vous.
Amicalement.
Jean-François Ortolo
--
Visitez le site http://www.pronostics-courses.fr/
donnant des Statistiques, Pronostics et Historiques graphiques
très élaborés.
Les Statistiques sont calculées d'après une base de données
allant du 1er Janvier 2000 jusqu'à très récemment.