awk: memaksakan status pengembalian?


17

Ini adalah kelanjutan dari pertanyaan saya sebelumnya .

Saya memvalidasi jumlah bidang di / etc / passwd menggunakan potongan praktis ini. Dalam contoh berikut, pengguna 'fieldcount1' dan 'fieldcount2' memiliki jumlah bidang yang salah:

$ 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

Seperti yang akan Anda perhatikan, awk akan keluar dengan status pengembalian 0. Dari sudut pandangnya, tidak ada masalah di sini.

Saya ingin memasukkan pernyataan awk ini ke dalam skrip shell. Saya ingin mencetak semua baris yang salah, dan mengatur kode kembali menjadi 1 (kesalahan).

Saya dapat mencoba untuk memaksakan status keluar tertentu, tetapi kemudian awk hanya mencetak satu baris:

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

Bisakah saya memaksa awk untuk keluar dengan status pengembalian '1', dan mencetak semua baris yang cocok?

Jawaban:


23

Simpan status dalam variabel dan gunakan dalam ENDblok.

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

Baik sekali. Namun saya mengalami masalah memasukkan ini ke skrip bash. Saya mencoba menangkap status pengembalian pernyataan awk ini dengan menambahkan sesuatu seperti ; echo $?setelah pernyataan awk ini. Namun, echo $?tidak pernah dijalankan karena END {exit err}'skrip berakhir. Apakah ada cara untuk mengatur status pengembalian tanpa keluar?
Stefan Lasiewski

6
@StefanLasiewski exit errmengakhiri awk, itu tidak mengakhiri skrip. Apakah Anda memiliki set -eskrip itu? Jika demikian, Anda telah memerintahkan shell untuk keluar jika perintah mengembalikan status bukan nol; jika Anda ingin menguji statusnya, gunakan if awk …; then echo ok; else echo fail; fi.
Gilles 'SO- stop being evil'

@ Giles: Ya, skrip ini memang telah set -edisetel. Itu menjelaskan perilaku aneh yang saya lihat. Terima kasih telah menunjukkannya.
Stefan Lasiewski

1
Jika Anda berencana untuk menggunakan output dengan &&operator bash , perlu diingat bahwa "0 benar tetapi salah adalah 1 di shell" .
Skippy le Grand Gourou

7

Saya mencari sesuatu yang mirip dengan grep, di mana ia akan keluar 1 jika kecocokan tidak ditemukan. Berikut ini adalah setara dengan awk:

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

Contoh


0

Ini tidak menjawab persyaratan persis OP, tetapi jika Anda hanya peduli dengan kode pengembalian, dan tidak perlu mencetak baris yang cocok, mirip dengan grep -q, maka Anda dapat memodifikasi jawaban @geekasaur untuk keluar setelah pertandingan pertama, yang untuk input besar file akan menghemat waktu jika kesalahan lebih awal dalam file. Semoga /etc/passwdtidak memenuhi syarat untuk Anda!

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

1
awk -F: 'NF != 7 {exit 1}'akan melakukan hal yang sama.
Stéphane Chazelas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.