$ 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
l'exécution de find-Host-test
a pour résultat
$ 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';
Pourquoi la disparition de "t" du dossier de test?
Votre invocation sed
est fausse.
sed 's/$Host = 127.0.0.1/$Host = localhost/' "$i"
Voir la page de manuel de sed
:
sed [OPTION]... {script-only-if-no-other-script} [input-file]
Le fichier d'entrée est le dernier argument, pas le premier.
Note importante: t
dans sed
est appelé une étiquette. Après t
, le nom de l'étiquette suit. Dans votre cas, c'est le nom du fichier d'entrée sans le t
initial. sed
essaie donc de passer à une étiquette appelée est/sub2/configuration.php
, que sed
ne peut trouver nulle part. La deuxième expression s///g
n'est jamais exécutée.
La bonne réponse du chaos a déjà donné la raison pour laquelle votre sed
ne fonctionne pas.
Laissez-moi aller un peu plus loin pour indiquer une autre façon de parcourir votre fichier, puisque vous utilisez des étapes inutiles:
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"
Différences:
Vous utilisez for i in $(cat test-paths.txt)
(enfin, avec des backticks, mais je ne sais pas comment les citer). C'est bon, mais il vaut mieux utiliser une belle boucle while
en faisant while read line; do ... done < file
. De cette façon, vous lisez une ligne à la fois. Voir une discussion plus large sur le sujet dans Pour lire des lignes plutôt que des mots, dirigez/redirigez vers une boucle 'en lecture'.
De plus, utiliser des backticks est déconseillé. Il est préférable d'utiliser $()
, car il est possible de les imbriquer. (En fait, nous avons déjà observé que c'était même mauvais en postant une réponse ici :))
Il n'est pas nécessaire de grep "something"
puis de vérifier l'état $?
. Vous pouvez directement utiliser grep -q
pour cela.
Certaines de ces suggestions peuvent également être trouvées en collant votre script dans http://www.shellcheck.net/ .