awk: forçando um status de retorno?


17

Este é um seguimento da minha pergunta anterior .

Estou validando o número de campos em / etc / passwd usando este snippit útil. No exemplo a seguir, os usuários 'fieldcount1' e 'fieldcount2' têm o número errado de campos:

$ awk -F: ' NF!=7 {print}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
fieldcount2:blah::blah:1002:100:fieldcount2:/home/fieldcount2:/bin/bash:
$ echo $?
0

Como você notará, o awk sairá com um status de retorno igual a 0. Do ponto de vista dele, não há problemas aqui.

Gostaria de incorporar essa declaração do awk em um script de shell. Gostaria de imprimir todas as linhas com erro e definir o código de retorno como 1 (erro).

Posso tentar forçar um status de saída específico, mas o awk apenas imprime uma única linha:

$ awk -F: ' NF!=7 {print ; exit 1}' /etc/passwd
fieldcount1:x:1000:100:fieldcount1:/home/fieldcount1:/bin/bash::::
$ echo $?
1

Posso forçar o awk a sair com o status de retorno '1' e imprimir todas as linhas correspondentes?

Respostas:


23

Mantenha o status em uma variável e use-o em um ENDbloco.

awk -F: 'NF != 7 {print; err = 1}
         END {exit err}' /etc/passwd

Muito bom. No entanto, estou tendo problemas para incorporar isso em um script bash. Estou tentando capturar o status de retorno dessa declaração do awk adicionando algo como ; echo $?depois dessa declaração do awk. No entanto, echo $?nunca é executado porque END {exit err}'finaliza o script. Existe uma maneira de definir o status de retorno sem sair?
Stefan Lasiewski

6
@StefanLasiewski exit errfinaliza o awk, não finaliza o script. Você tem set -enesse roteiro, por acaso? Nesse caso, você disse ao shell para sair se um comando retornar um status diferente de zero; se você quiser testar o status, use if awk …; then echo ok; else echo fail; fi.
Gilles 'SO- stop be evil'

@ Giles: Sim, este script foi set -edefinido. Isso explica o comportamento estranho que estou vendo. Obrigado por apontar isso.
Stefan Lasiewski

1
Se você planeja usar a saída com o &&operador do bash , vale lembrar que "0 é verdadeiro, mas falso é 1 no shell" .
Skippy le Grand Gourou

7

Eu estava procurando por algo semelhante ao grep, onde sairá 1 se uma correspondência não for encontrada. Aqui está o equivalente ao awk:

awk '
BEGIN   {z=1}
/bravo/ {z=0; print}
END     {exit z}
' alpha.txt

Exemplo


0

Isso não responde aos requisitos exatos do OP, mas se você se preocupa apenas com o código de retorno e não precisa imprimir as linhas correspondentes, grep -qé possível modificar a resposta do @geekasaur para sair após a primeira correspondência, o que gera uma entrada enorme arquivos economizariam tempo se o erro ocorresse no início do arquivo. Espero /etc/passwdque não se qualifique para você!

awk -F: 'NF != 7 {err = 1; exit;}
     END {exit err}' /etc/passwd

1
awk -F: 'NF != 7 {exit 1}'fará o mesmo.
Stéphane Chazelas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.