使用sed和find在多个文件中进行更改

时间:2015-07-08 18:41:46

标签: regex bash sed find

我必须经历100多个网站,并在所有网站的同一个文件中添加两行(sendmail1.php)。 老板要我手工复制/粘贴这些东西,但是GOT是一种更简单的方法,所以我试图用find和sed来做,这两者显然我用得不好。我只想在dir中运行一个包含所有站点的目录。

我有这个:

#!/bin/bash

read -p "Which file, sir? : " file

# find . -depth 1  -type f -name 'sendmail1.php' -exec \


sed -i 's/require\ dirname\(__FILE__\).\'\/includes\/validate.php\';/ \
        a require_once dirname\(__FILE__\).\'\/includes\/carriersoft_email.php\';' $file


sed -i 's/\else\ if\($_POST[\'email\']\ \&\&\ \($_POST\'work_email\'\]\ ==\ \"\"\)\){/ \
        a\t$carriersoft_sent = carriersoft_email\(\);' $file

exit 0

目前,我试图在这里整理sed并测试脚本时发现了这个发现,但我想解决这两个问题。 我想我并没有在sed位中逃避必要的东西,但我不断改过它并改变它并得到不同的错误(有时候“未完成的s /陈述”其他时间。其他的东西。

重点是我必须这样做:

require dirname(__FILE__).'/includes/validate.php';下方,添加以下行:

require_once dirname(__FILE__).'/includes/carriersoft_email.php';

else if($_POST['email'] && ($_POST['work_email'] == "")){下,添加以下行:

$carriersoft_sent = carriersoft_email();

我想将这4小时的复制/意大利面噩梦变成2分钟懒惰的管理类型脚本并完成工作。 但是我的fu对sed或者发现并不强烈...... 至于发现,我得到“路径必须先于表达式:1” 我在这里找到了解决这个错误的问题,但是指出使用''来包围文件名应该解决它,但是它没有用。

3 个答案:

答案 0 :(得分:2)

保持简单并且只使用awk,因为awk可以使用字符串操作,这与sed不同,后者仅适用于具有其他警告的RE:

find whatever |
while IFS= read -r file
do
    awk '
        { print }
        index($0,"require dirname(__FILE__).\047/includes/validate.php\047;") {
            print "require_once dirname(__FILE__).\047/includes/carriersoft_email.php\047;"
        }
        index($0,"else if($_POST[\047email\047] && ($_POST[\04work_email\047] == "")){") {
            print "$carriersoft_sent = carriersoft_email();"
        }
    ' "$file" > /usr/tmp/tmp_$$ &&
    mv /usr/tmp/tmp_$$ "$file"
done

使用GNU awk,您可以使用-i inplace来避免手动指定tmp文件名,如果您愿意,就像使用sed -i一样。

\047是在单引号分隔的脚本中指定单引号的一种方法。

答案 1 :(得分:1)

试试这个:

sed -e "s/require dirname(__FILE__).'\/includes\/validate.php';/&\nrequire_once dirname(__FILE__).'\/includes\/carriersoft_email.php'\;/" \
-e "s/else if(\$_POST\['email'\] && (\$_POST\['work_email'\] == \"\")){/&\n\$carriersoft_sent = carriersoft_email();/"                   \
file

注意:我还没有使用-i标志。确认它适合您后,您可以使用-i标志。此外,我已将两个sed命令合并为一个-e选项。

答案 2 :(得分:1)

我认为如果不是s你使用了另一个精确命令a,那就更清楚了。要输出一个已更改的文件,请使用以下内容创建一个脚本(例如script.sed):

/require dirname(__FILE__)\.'\/includes\/validate.php';/a\
require_once dirname(__FILE__).'/includes/carriersoft_email.php';
/else if(\$_POST\['email'\] && (\$_POST\['work_email'\] == "")){/a\
$carriersoft_sent = carriersoft_email();

并运行sed -f script.sed sendmail1.php

要在所有文件中应用更改,请运行:

find . -name 'sendmail1.php' -exec sed -i -f script.sed {} \;

-i会导致sed就地更改文件。

在此类操作中始终建议执行备份,并在运行命令后检查确切的更改。 :)