Linux SED 搜索每行替换多个
我需要用我为清除超级全局变量免受 xss 攻击而编写的 PHP 函数替换客户端网站中的一大堆 PHP 超级全局变量。
原始代码可能如下所示:
echo $_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2'];
我需要它如下所示:
echo MYCLASS::myfunction($_REQUEST['HELLO1']) . ' AND ' . MYCLASS::myfunction($_REQUEST['HELLO2']);
主要问题是,我需要对 100 多个文件进行搜索/替换!哎呀!
所以我的解决方案是这样的(在linux shell中):
sudo sed -i 's/\$_REQUEST[.*\]/MYCLASS::myfunction(&)/g' *.php
只要每行只出现一个“$_REQUEST”实例,这种方法就很有效...但是,对于多个实例,它会搞砸并执行以下操作:
echo MYCLASS::myfunction($_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2']);
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.
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! Yikes!
So my solution was this (in 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:
echo MYCLASS::myfunction($_REQUEST['HELLO1'] . ' AND ' . $_REQUEST['HELLO2']);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
问题是
.*
是贪婪的,会找到它能找到的最长的可能匹配。要解决此问题,请使用[^]]*
代替,这样您就不会无意中抓住一组额外的方括号。在其他正则表达式方言中,您也可以编写
.*?
以使通配符非贪婪,但这似乎在 sed 中不起作用(至少在我的版本中不起作用,甚至与sed -r
)。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.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 withsed -r
).尝试这个 sed 命令:
或在 perl 中:
Try this sed command:
or in perl:
在 Perl 中,以下脚本将在您向脚本传递您感兴趣的文件的名称时起作用
假设脚本是 t.pl 并且您的文件是 file.php
输出回 file.php
perl t.pl 文件.php >文件.php
输出到另一个文件,这样就不会覆盖原始文件
perl t.pl 文件.php > another_file.php
退出;
In Perl, the following script will work where you pass the script the name of the file you are interested in
lets say the script is t.pl and your file is file.php
to output back to file.php
perl t.pl file.php > file.php
to output to another file so you don't overwrite your original
perl t.pl file.php > another_file.php
exit;
sed 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g'
sed 's/\$_REQUEST\[[^]]*\]/MYCLASS::myfunction(&)/g'
这应该可以做到:
我在匹配
]
时遇到了很多麻烦,所以我用\x5d
进行了下注。This should do it:
I had a lot of trouble matching
]
, so I've punted with\x5d
.