$ cat test-paths.txt
test/sub2/configuration.php
test/sub3/configuration.php
test/configuration.php
test/sub1/configuration.php
$ cat find-host-test
#!/bin/bash
for i in `cat test-paths.txt`
do
echo $i
grep "public \$host = '127.0.0.1';" $i
#echo $?
if [ $? -eq 0 ]
then
echo "there's config file"
sed $i 's/$host = 127.0.0.1/$host = localhost/'
echo "changed to"
grep "public \$host =" $i
fi
done
运行find-host-test
导致
$ bash find-host-test
test/sub2/configuration.php
public $host = '127.0.0.1';
there's config file
sed: can't find label for jump to `est/sub2/configuration.php'
changed to
public $host = '127.0.0.1';
test/sub3/configuration.php
test/configuration.php
public $host = '127.0.0.1';
there's config file
sed: can't find label for jump to `est/configuration.php'
changed to
public $host = '127.0.0.1';
test/sub1/configuration.php
public $host = '127.0.0.1';
there's config file
sed: can't find label for jump to `est/sub1/configuration.php'
changed to
public $host = '127.0.0.1';
为什么测试文件夹中的“t”消失了?
答案1
你的sed
调用是错误的。
sed 's/$host = 127.0.0.1/$host = localhost/' "$i"
请参阅手册页sed
:
sed [OPTION]... {script-only-if-no-other-script} [input-file]
输入文件是最后一个参数,而不是第一个参数。
有趣的旁注: t
insed
称为标签。t
标签名称之后紧随其后。在您的例子中,它是不带前导t
.的输入文件名sed
,因此尝试跳转到名为 的标签est/sub2/configuration.php
,但sed
在任何地方都找不到该标签。第二个表达式s///g
永远不会执行。
答案2
您的程序无法正常工作的原因sed
已由 Chaos 的好答案给出。
让我更进一步指出循环遍历文件的另一种方法,因为您使用了一些不必要的步骤:
while IFS= read -r file
do
echo "$file"
if grep -q "public \$host = '127.0.0.1';" "$file"; then
echo "there's config file"
sed 's/$host = 127.0.0.1/$host = localhost/' "$file"
echo "changed to"
grep "public \$host =" "$file"
fi
done < "test-paths.txt"
差异:
你正在使用
for i in $(cat test-paths.txt)
(好吧,用反引号,但我不知道如何引用它们)。这是可以的,但最好使用一个漂亮的while
循环来做while read line; do ... done < file
。这样你一次可以读一行。请参阅有关该主题的更广泛讨论要读取行而不是单词,请通过管道/重定向到“while read”循环。此外,使用反引号已被弃用。最好使用
$()
,因为可以嵌套它们。(事实上,我们已经观察到,在这里发布答案时,这甚至很糟糕:))无需
grep "something"
再检查$?
状态。您可以直接使用grep -q
它。您也可以通过将脚本粘贴到以下位置来找到其中一些建议http://www.shellcheck.net/。