2011-04-29 5 views
3

J'ai un doosey ici. Je suis nouveau à Linux shell si nue avec moi ...Linux SED recherche remplacer multiple par ligne

J'ai besoin de remplacer tout un tas de super globales PHP dans un site Web clients avec une fonction PHP que j'ai faite pour nettoyer les superglobales des attaques xss.

Voici ce que le code d'origine pourrait ressembler à:

echo $_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2']; 

j'ai besoin de ressembler à ceci:

echo MYCLASS::myfunction($_REQUEST['HELLO1']) . ' AND ' . MYCLASS::myfunction($_REQUEST['HELLO2']); 

La question principale, je dois faire une recherche/remplacement sur plus 100 fichiers! Yikes!

Donc ma solution était ce (en shell linux):

sudo sed -i 's/\$_REQUEST[.*\]/MYCLASS::myfunction(&)/g' *.php 

Cela fonctionne très bien que longue, comme une seule instance de « $ _REQUEST » se produit par ligne ... Cependant, avec plusieurs instances, il visser et fait ceci:

echo MYCLASS::myfunction($_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2']); 

Je tire maintenant mes cheveux!

Est-ce que je peux espérer trouver des experts en shell Linux?

Répondre

1

Essayez cette commande sed:

sed -i.bak 's/\$_REQUEST\[\([^]]*\)\]/MYCLASS::myfunction(\1)/g' *.php 

ou en Perl:

perl -pe 's/\$_REQUEST\[([^]]*)\]/MYCLASS::myfunction(\1)/g' file.php 
+0

c'était beaucoup plus rapide que le script Perl .. merci! –

+0

Vous êtes les bienvenus, je vous ai fourni un perl 1 doublure ainsi en réponse ci-dessus pour faire la même chose. – anubhava

+0

J'ai un problème cependant .. Il remplace $ _REQUEST [''] WITH $ _REQUEST ('') aucune idée de comment réparer? –

0

Cela devrait le faire:

sed -i "s/\$_REQUEST\[\([^\x5d]*\)\]/MYCLASS::myfunction(\1)/g" *.php 

J'ai eu beaucoup de mal correspondant ], donc je l'ai écartaient avec \x5d.

+0

Je reçois une « expression -e # 1, char 43: référence non valide \ 1 sur 's; command –

+0

Essayez de le faire' s/\ $ _ DEMANDE \ [\ ([^ \]] [^ \]] *) \]/.... ' – shellter

2

Le problème est que .* est gourmand et qu'il trouvera la correspondance la plus longue possible. Pour contourner cela, utilisez à la place [^]]* afin de ne pas saisir par inadvertance un jeu supplémentaire de crochets.

sudo sed -i 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g' *.php 

Dans d'autres dialectes regex, vous pouvez écrire .*? pour rendre le caractère générique non gourmand, mais cela ne semble pas travailler dans sed (au moins pas dans ma version, pas même avec sed -r).

+0

Nous vous remercions de votre aide. est intéressant, la réponse ne marche pas, nous essayons le. *? ks! –

+0

On dirait que votre réponse a aidé à résoudre celui-ci. Merci. –

1

En Perl, le script suivant fonctionnera où vous passez le script le nom du fichier que vous êtes intéressé par
permet de dire que le script est t.pl et votre fichier est file.php
à la sortie de retour vers le fichier .php
perl t.pl file.php> file.php
à la sortie vers un autre fichier afin de ne pas écraser votre original
perl t.pl file.php> another_file.php

#!/usr/bin/perl 

$FILE_NAME = $ARGV[0]; 

open (FILE_NAME) or die ("Could not open FILE_NAME information file: $FILE_NAME \n"); 
@file_contents = <FILE_NAME>; 
close (FILE_NAME); 


foreach $line (@file_contents) { 
     chomp($line); 
     $line =~ s/\$_REQUEST\[.*?\]/MYCLASS\:\:myfunction\($&\)/g; 
     print $line." \n"; 
} 

sortie;

+0

Je ne suis pas sûr d'avoir obtenu le marquage de la solution car je n'ai pas utilisé sed mais je suis content que ce script Perl fonctionne pour vous. – Troy

1

sed 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g'