comme @cnicutar l'a commenté, le code de retour d'une commande signifie si la commande a été exécutée avec succès. n'a rien à voir avec la logique que vous avez implémentée dans les codes/scripts.
donc si vous avez :
echo "foo"|sed '/bar/ s/a/b/'
sed renverra 0
mais si vous écrivez des erreurs de syntaxe/d'expression, ou si l'entrée/le fichier n'existe pas, sed ne peut pas exécuter votre requête, sed renverra 1.
solution de contournement
ce n'est en fait pas une solution de contournement . sed a q
commande :(à partir de la page de manuel) :
q [exit-code]
ici, vous pouvez définir le code de sortie comme vous le souhaitez. Par exemple '/foo/!{q100}; {s/f/b/}'
sortira avec le code 100 si foo
n'est pas présent, et sinon effectuer la substitution f->b et sortir avec le code 0.
Cas correspondant :
kent$ echo "foo" | sed '/foo/!{q100}; {s/f/b/}'
boo
kent$ echo $?
0
Cas sans correspondance :
kent$ echo "trash" | sed '/foo/!{q100}; {s/f/b/}'
trash
kent$ echo $?
100
J'espère que cela répond à votre question.
modifier
Je dois ajouter que l'exemple ci-dessus est juste pour le traitement d'une ligne. Je ne connais pas votre besoin exact. quand vous voulez obtenir exit 1
. une ligne sans correspondance ou l'ensemble du fichier. Si le fichier entier ne correspond pas à la casse, vous pouvez envisager awk, ou même faire un grep
avant votre traitement de texte...
Cela pourrait fonctionner pour vous (GNU sed):
sed '/search-string/{s//replacement-string/;h};${x;/./{x;q0};x;q1}' file
Si le search-string
est trouvé, il sera remplacé par replacement-string
et en fin de fichier sed
sortira avec 0
Code de retour. Si aucune substitution n'a lieu, le code de retour sera 1
.
Une explication plus détaillée :
Dans sed, l'utilisateur dispose de deux registres :l'espace de motif (PS) dans lequel la ligne courante est chargée (moins le saut de ligne) et un registre de réserve appelé l'espace de maintien (HS) qui est initialement vide.
L'idée générale est d'utiliser le SH comme indicateur pour indiquer si une substitution a eu lieu. Si le SH est toujours vide à la fin du fichier, alors aucune modification n'a été apportée, sinon des modifications ont eu lieu.
La commande /search-string/
correspond à search-string
avec tout ce qui se trouve dans le PS et s'il contient le search-string
les commandes entre les accolades suivantes sont exécutées.
Tout d'abord la substitution s//replacement-string/
(sed utilise la dernière expression régulière c'est-à-dire le search-string
, si le côté gauche est vide, donc s//replacement-string
est identique à s/search-string/replacement-string/
) et ensuite le h
commande fait une copie du PS et la place dans le HS.
La commande sed $
est utilisé pour reconnaître la dernière ligne d'un fichier et ce qui suit se produit alors.
D'abord le x
La commande permute les deux registres, de sorte que le HS devient le PS et le PS devient le HS.
Ensuite, le PS est recherché pour n'importe quel caractère /./
(.
signifie correspondre à n'importe quel caractère) rappelez-vous que le HS (maintenant le PS) était initialement vide jusqu'à ce qu'une substitution ait eu lieu. Si la condition est vraie, le x
est à nouveau exécuté suivi de q0
commande qui termine tous les traitements sed et définit le code de retour sur 0
. Sinon le x
la commande est exécutée et le code de retour est défini sur 1
.
N.B. bien que le q
quitte le traitement de sed, cela n'empêche pas le PS d'être réassemblé par sed et imprimé normalement.
Autre alternative :
sed '/search-string/!ba;s//replacement-string/;h;:a;$!b;p;x;/./Q;Q1' file
ou :
sed '/search-string/,${s//replacement-string/;b};$q1' file
Ces réponses sont trop compliquées. Qu'y a-t-il de mal à écrire un peu de script shell qui utilise grep pour déterminer si la chose que vous voulez remplacer est là, puis à utiliser sed pour la remplacer ?
grep -q $TARGET_STRING $file
if [ $? -eq 0 ]
then
echo "$file contains the old site"
sed -e "s|${TARGET_STRING}|${NEW_STRING}|g" ....
fi