awk: forzare uno stato di ritorno?


17

Questo è un seguito alla mia domanda precedente .

Sto convalidando il numero di campi in / etc / passwd usando questo pratico frammento. Nel seguente esempio, "fieldcount1" e "fieldcount2" degli utenti hanno un numero errato di campi:

$ 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

Come noterai, awk uscirà con uno stato di ritorno di 0. Dal suo punto di vista, qui non ci sono problemi.

Vorrei incorporare questa affermazione awk in uno script di shell. Vorrei stampare tutte le righe che sono errori e impostare il codice di ritorno su 1 (errore).

Posso provare a forzare un particolare stato di uscita, ma poi awk stampa solo una singola riga:

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

Posso forzare awk a uscire con uno stato di ritorno di '1' e stampare tutte le righe corrispondenti?

Risposte:


23

Mantieni lo stato in una variabile e usalo in un ENDblocco.

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

Molto buona. Tuttavia sto incontrando problemi nell'incorporarlo in uno script bash. Sto cercando di acquisire lo stato di ritorno di questa dichiarazione awk aggiungendo qualcosa di simile a ; echo $?questa dichiarazione awk. Tuttavia, echo $?non viene mai eseguito perché END {exit err}'termina lo script. C'è un modo per impostare lo stato di ritorno senza uscire?
Stefan Lasiewski,

6
@StefanLasiewski exit errtermina awk, non termina lo script. Hai set -ein quella sceneggiatura, per caso? In tal caso, hai detto alla shell di uscire se un comando restituisce uno stato diverso da zero; se si desidera verificare lo stato, utilizzare if awk …; then echo ok; else echo fail; fi.
Gilles 'SO- smetti di essere malvagio' il

@Giles: Sì, questo script è set -eimpostato. Questo spiega lo strano comportamento che sto vedendo. Grazie per la segnalazione.
Stefan Lasiewski,

1
Se pensate di usare l'output con l' &&operatore di bash , vale la pena ricordare che "0 è vero ma falso è 1 nella shell" .
Skippy le Grand Gourou,

7

Stavo cercando qualcosa di simile a grep, dove uscirà 1 se non viene trovata una corrispondenza. Ecco l'equivalente con awk:

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

Esempio


0

Questo non risponde ai requisiti esatti del PO, ma se ti preoccupi solo del codice di ritorno e non hai bisogno di stampare le linee che corrispondono, in modo simile grep -q, puoi modificare la risposta di @geekasaur per uscire dopo la prima corrispondenza, che per un immenso input i file farebbero risparmiare tempo se l'errore fosse all'inizio del file. Spero /etc/passwdnon si qualifichi per te!

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

1
awk -F: 'NF != 7 {exit 1}'farà lo stesso.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.