for i in `find `pwd` -name .htaccess -exec grep -q "RedirectMatch" {} \; -print`; do $i | sed -i 's/RedirectMatch/#RedirectMatch/g'; done
所以我的命令应该搜索所有的.htaccess文件并grep其中包含“RedirectMatch”的文件,一旦完成它应该通过管道输出来注释掉该行。
正在运行
find `pwd` -name .htaccess -exec grep -q "RedirectMatch" {} \; -print
实际上给了我一个包含“RedirectMatch”的.htaccess文件的列表,但是当我在我的循环中运行它时会抛出一大堆文件,甚至是那些没有命名的文件.htaccess。
有什么想法吗?感谢所有帮助。
答案 0 :(得分: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命令的调用)
答案 1 :(得分:0)
该命令出现了一些问题:
首先,你需要逃避嵌套反引号,让它们按你认为的方式工作:
`find \`pwd\` -name .htaccess -exec grep -q "RedirectMatch" {} \; -print`
或使用首选的子shell表示法:
$(find $(pwd) -name .htaccess -exec grep -q "RedirectMatch" {} \; -print)
其次,在使用就地sed
标志时,您无法输入-i
。我不确定你在这里想要完成什么,但我认为你应该在每个文件上运行sed
,如果字符串不在那里,什么都不会被替换,并且它不会有任何低效率。你正在做什么不会以任何方式编辑任何文件,你只是在stdin的文件名上运行sed
,而不是文件本身!所以像这样:
find . -name .htaccess -exec sed -i "" 's/RedirectMatch/#RedirectMatch/g' {} \;
注意:-i
之后的引号对于sed
(在darwin上运行)是必需的,它们满足-i
标志对参数的需要,大多数{{}可能不需要1}}秒。另外,正如其他人提到的那样,没有必要调用sed
,因此我将其与pwd
进行了交换。
答案 2 :(得分: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)
但请注意,使用sed -i
不可移植 - 在POSIX中未指定-i
标志,并且许多操作系统不支持它。您最好使用ex
进行编辑,该编辑由POSIX指定,并使用与vi
中的命令模式相同的语法进行编辑:
while IFS='' read -r -d '' filename; do
ex "$filename" -s - <<<'%s/^\([^#]*\)RedirectMatch/\1#RedirectMatch/'$'\n''x'
done < <(find . -name .htaccess -print0)