用 sed 更改字符串,它去哪儿了?

用 sed 更改字符串,它去哪儿了?
$ 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]

输入文件是最后一个参数,而不是第一个参数。

有趣的旁注: tinsed称为标签。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/

相关内容