Comment obtenir l'état de sortie lorsque j'utilise la commande sed?

11

La grepcommande donne à un état de sortie:

$echo "foo.bar" | grep -o foo
foo
$echo $?
0
$echo "foo.bar" | grep -o pop
$echo $?
1  

Mais je dois utiliser sedet j'ai réalisé qu'il n'a pas de statut de sortie:

$echo "foo.bar" | sed 's/bar.*$//'
foo.
$echo $?
0
$echo "foo.bar" | sed 's/pop.*$//'
foo.bar
$echo $?
0  

Je sais que je devrais jouer avec l' -qoption, mais je n'ai pas réussi.

Josef Klimuk
la source
7
Notez que sedtrès certainement a un statut de sortie, il ne fait tout simplement pas ce dont vous avez besoin ici. Si la sedcommande échoue, par exemple, si vous essayez de l'exécuter sur un fichier auquel vous n'avez pas accès en écriture ou qui n'existe pas, se sedfermera avec un état de sortie différent de 0. Le statut de sortie indique simplement si sedvous avez réussi à faire ce que vous lui avez demandé de faire et s'il a echo "foo.bar" | sed 's/pop.*$//'été correctement exécuté. Il a supprimé toutes les lignes avec pop. Qu'il n'y ait pas de telles lignes est sans importance, la commande fonctionnait toujours.
terdon
@Zanna J'allais poster une réponse, mais je sentais que cela ne répond pas vraiment à la question. Cela explique seulement une idée fausse, mais ne fournit pas de solution utile comme Steeldriver ci-dessous. Un commentaire semblait donc plus approprié.
terdon

Réponses:

13

Vous pouvez utiliser q n pour quitter avec le statut de sortie n - mais pour le rendre utile, vous devrez également utiliser des branchements et un contrôle de flux :

t
branche conditionnellement (c'est-à-dire: saute à une étiquette) uniquement si une s/// commande a réussi depuis que la dernière ligne d'entrée a été lue ou qu'une autre branche conditionnelle a été prise.

Il est probablement préférable de choisir une valeur pour n distincte de l'une des valeurs de statut de sortie standard:

Un état de sortie de zéro indique la réussite et une valeur différente de zéro indique l'échec. GNU 'sed' renvoie les valeurs d'erreur d'état de sortie suivantes:

0
 Successful completion.

1
 Invalid command, invalid syntax, invalid regular expression or a
 GNU 'sed' extension command used with '--posix'.

2
 One or more of the input file specified on the command line could
 not be opened (e.g.  if a file is not found, or read permission is
 denied).  Processing continued with other files.

4
 An I/O error, or a serious processing error during runtime, GNU
 'sed' aborted immediately.

Donc par exemple

$ echo "foo.bar" | sed 's/bar.*$//; t; q42' ; echo $? 
foo.
0

tandis que

$ echo "foo.bar" | sed 's/baz.*$//; t; q42' ; echo $? 
foo.bar
42

Si vous souhaitez omettre l'impression par défaut de l'espace de motif, remplacez-le qpar Q(notez qu'il Qs'agit d'une extension GNU).

tournevis
la source
1

Voici comment rechercher des expressions rationnelles avec sed et mettre en surbrillance les correspondances , ou retourner le code de sortie (5) si aucune correspondance n'a été trouvée:

C'est input.txt:

hello there
my dear old friend
a lot of things
we'll pass along the end

Voici ma fonction pour tout imprimer + surligner les correspondances + retourner le code de sortie:

highlight()
{
  pattern=$1
  shift
  sed '/'"${pattern}"'/,${s//\x1b[32m&\x1b[0m/g;b};$q5' "$@"
}

$ mettre en évidence "lo \ | end" input.txt || echo -e "\ n * Aucune correspondance trouvée *"

hel lo
mon cher vieux fri fin
un lo t de choses que
nous passerons un lo ng la fin

Lorsqu'il n'y a pas de correspondance, il renverra le code de sortie (5). Vous pouvez l' utiliser avec chat et pipe | ainsi que:

$ cat input.txt | mettez en surbrillance "hot \ | et" || echo -e "\ n * Aucune correspondance trouvée *"

bonjour
mon cher vieil ami
beaucoup de choses que
nous passerons à la fin

* Pas de résultat trouvé *

Merci à https://unix.stackexchange.com/a/405725/43233 - Je l'utilise + l'option de sortie sed.

Noam Manos
la source