Pertama, mari kita tunjukkan head
itu sebenarnya bekerja dengan benar:
$ printf '\xef\xbb\xbf' >file
$ head -c 3 file
$ head -c 3 file | hexdump -C
00000000 ef bb bf |...|
00000003
Sekarang, mari buat fungsi kerja has_bom
. Jika grep
Anda mendukung -P
, maka salah satu opsinya adalah:
$ has_bom() { head -c3 "$1" | LC_ALL=C grep -qP '\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
Saat ini, hanya GNU grep
mendukung -P
.
Pilihan lainnya adalah menggunakan $'...'
bash :
$ has_bom() { head -c3 "$1" | grep -q $'\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
ksh
dan zsh
juga mendukung $'...'
tetapi konstruk ini bukan POSIX dan dash
tidak mendukungnya.
Catatan:
-
Penggunaan
return $?
eksplisit adalah opsional. Secara default, fungsi akan kembali dengan kode keluar dari perintah terakhir yang dijalankan. -
Saya telah menggunakan formulir POSIX untuk mendefinisikan fungsi. Ini setara dengan bentuk bash tetapi memberi Anda satu masalah yang lebih sedikit untuk ditangani jika Anda harus menjalankan fungsi di bawah shell lain.
-
bash menerima penggunaan karakter
-
dalam nama fungsi tetapi ini adalah fitur yang kontroversial. Saya menggantinya dengan_
yang lebih diterima secara luas. (Untuk informasi lebih lanjut tentang masalah ini, lihat jawaban ini.) -
-q
opsi untukgrep
membuatnya diam, artinya masih menyetel kode keluar yang tepat tetapi tidak mengirim karakter apa pun ke stdout.
Saya menerapkan hal berikut untuk baris baca pertama:
read c
if (( "$(printf "%d" "'${c:0:1}")" == 65279 )) ; then c="${c:1}" ; fi
Ini hanya menghapus BOM dari variabel.