Linux SED 搜索每行替换多个

发布于 2024-11-04 07:25:13 字数 652 浏览 1 评论 0原文

我需要用我为清除超级全局变量免受 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

半窗疏影 2024-11-11 07:25:14

问题是 .* 是贪婪的,会找到它能找到的最长的可能匹配。要解决此问题,请使用 [^]]* 代替,这样您就不会无意中抓住一组额外的方括号。

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

在其他正则表达式方言中,您也可以编写 .*? 以使通配符非贪婪,但这似乎在 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.

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).

绿萝 2024-11-11 07:25:14

尝试这个 sed 命令:

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

或在 perl 中:

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

Try this sed command:

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

or in perl:

perl -pe 's/\$_REQUEST\[([^]]*)\]/MYCLASS::myfunction(\1)/g' file.php
像极了他 2024-11-11 07:25:14

在 Perl 中,以下脚本将在您向脚本传递您感兴趣的文件的名称时起作用
假设脚本是 t.pl 并且您的文件是 file.php
输出回 file.php
perl t.pl 文件.php >文件.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\(
amp;\)/g;
       print $line." \n";
}

退出;

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

#!/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\(
amp;\)/g;
       print $line." \n";
}

exit;

黑白记忆 2024-11-11 07:25:14

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

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

隔岸观火 2024-11-11 07:25:14

这应该可以做到:

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

我在匹配 ] 时遇到了很多麻烦,所以我用 \x5d 进行了下注。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文