Como obtenho o status de saída ao usar o comando sed?

11

O grepcomando fornece um status de saída:

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

Mas preciso usar sede percebi que ele não tem status de saída:

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

Eu sei que devo brincar com a -qopção, mas não consegui.

Josef Klimuk
fonte
7
Observe que sedcertamente tem um status de saída, apenas não faz o que você precisa aqui. Se o sedcomando falhar, por exemplo, se você tentar executá-lo em um arquivo ao qual não tenha acesso de gravação ou que não exista, sedsairá com um status de saída diferente de 0. O status de saída apenas indica se sedconseguiu fazer o que você pediu e echo "foo.bar" | sed 's/pop.*$//'foi executado corretamente. Excluiu todas as linhas com pop. O fato de não haver essas linhas é irrelevante, o comando ainda funcionava.
terdon 16/05
@ Zanna, eu estava indo para postar uma resposta, mas eu senti que isso realmente não responde à pergunta. Isso apenas explica um equívoco, mas não fornece uma solução útil como a steeldriver. Portanto, um comentário parecia mais apropriado.
terdon 16/05

Respostas:

13

Você pode usar q n para sair com o status de saída n - mas, para tornar isso útil, você também precisará usar alguns Controle de Ramificação e Fluxo :

t
ramifica condicionalmente (isto é: pula para um rótulo) somente se um s/// comando tiver sido bem-sucedido desde que a última linha de entrada foi lida ou se outra ramificação condicional foi executada.

Provavelmente, é melhor escolher um valor para n que seja distinto de um dos valores de status de saída padrão:

Um status de saída zero indica êxito e um valor diferente de zero indica falha. GNU 'sed' retorna os seguintes valores de erro de status de saída:

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.

Então por exemplo

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

enquanto que

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

Se você deseja omitir a impressão padrão do espaço do padrão, substitua qpor Q(observe que Qé uma extensão GNU).

chave de aço
fonte
1

Veja como pesquisar regex com sed e destacar correspondências ou retornar o código de saída (5) se nenhuma correspondência encontrada:

Este é input.txt:

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

Aqui está minha função para Imprimir tudo + Realçar correspondências + Retornar código de saída:

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

$ destaque "lo \ | end" input.txt || eco -e "\ n * Nenhuma correspondência encontrada *"

hel lo
meus queridos fri velhos acabar
uma lo t de coisas
que vai passar uma lo ng a final

Quando não houver correspondência, ele retornará o código de saída (5). Você pode usá-lo com gato e cachimbo | também:

$ cat input.txt | destaque "quente \ | e" || eco -e "\ n * Nenhuma correspondência encontrada *"

olá,
meu querido velho amigo,
um monte de coisas
que passaremos no final

* Nenhuma combinação encontrada *

Graças a https://unix.stackexchange.com/a/405725/43233 - estou usando a opção + sed quit.

Noam Manos
fonte