-2
for i in `find `pwd` -name .htaccess -exec grep -q "RedirectMatch" {} \; -print`; do $i | sed -i 's/RedirectMatch/#RedirectMatch/g'; done

因此,我的命令几乎应该搜索所有 .htaccess 文件并 grep 其中包含“RedirectMatch”的文件,一旦完成,它应该通过管道传送到 sed 以注释掉该行。

跑步

find `pwd` -name .htaccess -exec grep -q "RedirectMatch" {} \; -print

实际上给了我一个包含“RedirectMatch”的.htaccess文件列表,但是当我在循环中运行它时,它会抛出一个巨大的文件列表,甚至是那些没有命名为.htaccess的文件。

有任何想法吗?感谢所有帮助。

4

3 回答 3

2

这是因为您的反引号:您的命令实际执行find,然后将字符串附加pwd到它,然后尝试执行其余的。

使用$(...)

for i in $(find $(pwd) -name .htaccess -exec grep -q "RedirectMatch" {} \; -print); do sed -i 's/RedirectMatch/#RedirectMatch/g' $i; done

并且由于默认find情况下如果没有指定,则默认在当前目录中查找,您可以进一步指定它:

for i in $(find -name .htaccess -exec grep -q "RedirectMatch" {} \; -print); do sed -i 's/RedirectMatch/#RedirectMatch/g' $i; done

(编辑:还修复了 sed 命令的调用)

于 2013-05-26T15:43:41.287 回答
0

该命令有一些问题:

首先,您需要避开嵌套的反引号,以便它们按照您认为的方式工作:

`find \`pwd\` -name .htaccess -exec grep -q "RedirectMatch" {} \; -print`

或使用首选的 subshel​​l 表示法:

$(find $(pwd) -name .htaccess -exec grep -q "RedirectMatch" {} \; -print)

其次,您不能sed在使用就地-i标志时通过管道输入。我不确定您要在这里完成什么,但我认为您应该只sed在每个文件上运行,如果字符串不存在,则不会替换任何内容,并且效率不会降低。您所做的不会以任何方式编辑任何文件,您只是sed在标准输入的文件名上运行,而不是文件本身!所以是这样的:

find . -name .htaccess -exec sed -i "" 's/RedirectMatch/#RedirectMatch/g' {} \;

注意: 后面的引号-i对于 my sed(在 darwin 上运行)是必需的,它们满足-i标志对参数的需要,大多数seds 可能不需要。同样正如其他人提到的那样,调用 topwd是不必要的,所以我将其换成了..

于 2013-05-26T16:11:31.957 回答
0

到目前为止,这里给出的答案是危险的错误 - 它们可以被操纵以包含任意输出(想想有人创建了一个名称中带有空格的单个文件,例如"./ /etc/passwd /.htaccess",从而导致您的脚本编辑/etc/passwd)。

while IFS='' read -r -d '' filename; do
  sed -i -e 's/^([^#]+)RedirectMatch/\1#RedirectMatch/' "$filename"
done < <(find . -name .htaccess -print0)

但是请注意, usingsed -i不是可移植的-i——POSIX 中没有指定该标志,并且许多操作系统不支持它。您最好使用exPOSIX 指定的编辑,并使用与以下命令模式相同的语法进行编辑vi

while IFS='' read -r -d '' filename; do
  ex "$filename" -s - <<<'%s/^\([^#]*\)RedirectMatch/\1#RedirectMatch/'$'\n''x'
done < <(find . -name .htaccess -print0)
于 2013-05-26T20:30:48.893 回答