Bagaimana secara programatik mendeteksi rasa awk (mis. Gawk vs nawk)


8

Saya menggunakan aplikasi command-line yang pada dasarnya adalah kumpulan skrip bash shell. Aplikasi ini ditulis untuk dijalankan pada BSD / OSX dan juga di Linux. Salah satu skrip bergantung pada awk. Ini berisi dua perintah awk: satu ditulis untuk nawk (implementasi standar BSD awk) dan satu ditulis untuk gawk (implementasi awk GNU).

Dua perintah awk yang dipermasalahkan tidak kompatibel dengan lingkungan yang berbeda; khususnya perintah nawk gagal saat dijalankan dengan gawk. Script memeriksa nama kernel (yaitu uname -s) untuk menentukan lingkungan host, dan kemudian menjalankan perintah awk yang sesuai. Namun saya lebih suka bekerja di Mac OS X dengan utilitas inti GNU terinstal, jadi skrip gagal berjalan dengan benar.

Dalam proses berpikir tentang cara terbaik untuk memperbaiki bug ini, terpikir oleh saya bahwa akan lebih baik mengetahui bagaimana secara terprogram membedakan antara rasa yang berbeda dari utilitas baris perintah umum, lebih disukai dengan cara yang relatif kuat dan portabel.

Saya perhatikan bahwa nawk tidak menerima bendera '-V' untuk mencetak informasi versi, jadi saya pikir sesuatu seperti yang berikut ini akan berfungsi:

awk -V &>/dev/null && echo gawk || echo nawk

Variasi lain dapat berupa:

awk -Wversion &>/dev/null && echo gawk || echo nawk

Ini sepertinya berfungsi pada dua lingkungan pengujian saya (OS X dan CentOS). Ini pertanyaan saya:

  • Apakah ini cara terbaik untuk pergi?
  • Apakah ada cara untuk memperluas ini untuk menangani variasi awk lainnya (mis. Mawk, jawk, dll.)?
  • Apakah layak khawatir tentang versi awk lainnya?

Saya juga harus menyebutkan bahwa saya tahu sedikit tentang awk.


Jika perintah awk tidak terlalu rumit, atau bahkan jika itu, Anda dapat mempertimbangkan porting ke perl atau sesuatu yang seragam.
Wildcard

Mari kita lihat versi awk awk -Wvalih-alih lingkungan host
Costas

1
Awk saya sangat lemah tapi saya percaya itu sangat sederhana. Saya sebenarnya sudah menulis ulang di bash murni. Tetapi ini adalah salah satu situasi di mana saya lebih tertarik untuk memuaskan rasa ingin tahu saya daripada benar-benar menyelesaikan masalah aslinya.
igal

@Costas Sesuatu seperti itu benar-benar terjadi pada saya, tapi saya tidak yakin seberapa rapuhnya itu; Saya tahu sedikit tentang awk. Saya telah menambahkan solusi saya saat ini ke posting saya.
igal

1
Salah satu alternatif adalah mengabaikan versi apa awkyang sedang digunakan, dan kode untuk spesifikasi POSIX sebagai gantinya.
chepner

Jawaban:


7
if awk --version 2>&1 | grep -q "GNU Awk"
then
    awk 'BEGIN {print "I am GNU Awk"}'

elif awk -Wv 2>&1 | grep -q "mawk"
then
    awk 'BEGIN {print "I am mawk"}'

else
    awk 'BEGIN {print "I might be nawk, might not be"}'
fi

Atau, tes awk adalah tautan simbolik:

awk=$( command -v awk )
[[ -L $awk ]] && readlink $awk # make some decision about the result of that

Yang ini tidak apa-apa ... tetapi ada beberapa variasi (sulit dibedakan) untuk awk-awk, nawk, dan versi BWK yang lebih baru. Bagi mereka, skrip sampel mungkin dirancang.
Thomas Dickey

3

Coba gunakan whichperintah dan gunakan kode keluarnya.

which nawk
if [[ $? == 0 ]]; then
    command="nawk"
else
    command="gawk"
fi

lalu format skrip Anda untuk menggunakan variabel sebagai perintah

$command '{print $1}` 

akan dibaca sebagai

nawk '{print $1}`

jika whichditemukan nawk. Kalau tidak, itu akan digunakangawk


1
karena commandbash builtin Anda mungkin ingin menggunakan nama yang berbeda untuk variabel Anda, dan Anda mungkin juga ingin melihat jawaban yang sangat terperinci tentang mengapa bagi banyak shell ada alternatif yang lebih baik whichdi unix.stackexchange.com/a/85250/109842
Eric Renouf

1

GNU Awk sering diinstal sebagai gawk, dengan awksebagai symlink untuknya pada sistem di mana GNU adalah default. Saya kira ini adalah kasus pada sistem BSD dan OS X, karena mereka sudah memiliki sendiri awk.

if gawk '{ exit; }' < /dev/null 2> /dev/null
then
    echo "gawk available"
else
    echo "gawk not available"
fi

Terima kasih atas masukannya. Ini adalah ide yang bagus dan Anda benar bahwa ini adalah kasus bagi saya pada OS X. Tapi saya berharap untuk solusi intrinsik, untuk berbicara.
igal

0

Retasan kotor

if nawk 'BEGIN { nawk-only-function() ;}' 
then 
   nawk -f nfile.awk ...
else 
   gawk -f gfile.awk ...
fi
  • di mana nawk-only-function() hanya ada dinawk

-2

Saya mungkin akan mencoba menyalahgunakan AC_PROG_AWK m4 makro di autoconf untuk memilih satu, memesannya dengan tepat. Ini mungkin berlebihan meskipun


Bisakah Anda mengedit untuk memberikan sedikit lebih detail tentang bagaimana Anda akan menggunakan makro itu untuk skenario ini?
Michael Homer

Itu tidak benar-benar tahu mana yang ditemukannya, tetapi hanya mencari implementasi awk dan memilih yang berdasarkan namanya.
Thomas Dickey
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.