简体   繁体   English

Linux SED 搜索替换每行多个

[英]Linux SED search replace multiple per line

I need to replace a whole bunch of PHP super globals in a clients website with a PHP function I made to clean the superglobals from xss attacks.我需要用 PHP function 替换客户网站中的一大堆 PHP 超级全局变量,以从 xss 攻击中清除超全局变量。

Here is what the original code might look like:以下是原始代码的样子:

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

I need it to look like this:我需要它看起来像这样:

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

The main issue, I need to do a search/replace on over 100 files!主要问题,我需要对 100 多个文件进行搜索/替换! Yikes!哎呀!

So my solution was this (in linux shell):所以我的解决方案是这样的(在 linux shell 中):

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

This works great as-long-as only one instance of "$_REQUEST" occurs per line... However with multiple instances, it screws up and does this:只要每行只出现一个“$_REQUEST”实例,这非常有效......但是对于多个实例,它会搞砸并执行以下操作:

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

The problem is that .* is greedy and will find the longest possible match it can.问题是.*是贪婪的,它会找到尽可能长的匹配。 To work around that use [^]]* instead so that you don't inadvertently grab up an extra set of square brackets.要解决这个问题,请改用[^]]* ,以免您无意中抓住一组额外的方括号。

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

In other regex dialects you could also write .*?在其他正则表达式方言中,您也可以编写.*? to make the wildcard non-greedy, but that doesn't appear to work in sed (at least not in my version, not even with sed -r ).使通配符不贪婪,但这似乎在 sed 中不起作用(至少在我的版本中不起作用,甚至在sed -r中也不起作用)。

In Perl, the following script will work where you pass the script the name of the file you are interested in在 Perl 中,以下脚本将起作用,您将脚本传递给您感兴趣的文件的名称
lets say the script is t.pl and your file is file.php假设脚本是 t.pl 而你的文件是 file.php
to output back to file.php到 output 返回文件。php
perl t.pl file.php > file.php perl t.pl 文件.php > 文件.php
to output to another file so you don't overwrite your original到 output 到另一个文件,这样你就不会覆盖原来的文件
perl t.pl file.php > another_file.php perl t.pl 文件.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";
}

exit;出口;

Try this sed command:试试这个 sed 命令:

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

or in perl:或在 perl 中:

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

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

This should do it:这应该这样做:

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

I had a lot of trouble matching ] , so I've punted with \x5d .我在匹配]时遇到了很多麻烦,所以我用\x5d

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM