Innanzitutto, dimostriamo che head
funziona effettivamente correttamente:
$ printf '\xef\xbb\xbf' >file
$ head -c 3 file
$ head -c 3 file | hexdump -C
00000000 ef bb bf |...|
00000003
Ora, creiamo una funzione funzionante has_bom
. Se il tuo grep
supporta -P
, allora un'opzione è:
$ has_bom() { head -c3 "$1" | LC_ALL=C grep -qP '\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
Attualmente, solo GNU grep
supporta -P
.
Un'altra opzione è usare $'...'
di bash :
$ has_bom() { head -c3 "$1" | grep -q $'\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
ksh
e zsh
supporta anche $'...'
ma questo costrutto non è POSIX e dash
non lo supporta.
Note:
-
L'uso di un
return $?
esplicito è facoltativo. La funzione, per impostazione predefinita, restituirà con il codice di uscita dell'ultimo comando eseguito. -
Ho usato il modulo POSIX per definire le funzioni. Questo è equivalente alla forma bash ma ti dà un problema in meno da affrontare se dovessi eseguire la funzione sotto un'altra shell.
-
bash accetta l'uso del carattere
-
in un nome di funzione, ma questa è una caratteristica controversa. L'ho sostituito con_
che è più ampiamente accettato. (Per ulteriori informazioni su questo problema, vedere questa risposta.) -
Il
-q
opzione agrep
lo rende silenzioso, nel senso che imposta comunque un codice di uscita corretto ma non invia alcun carattere a stdout.
Ho applicato quanto segue per la prima riga di lettura:
read c
if (( "$(printf "%d" "'${c:0:1}")" == 65279 )) ; then c="${c:1}" ; fi
Questo rimuove semplicemente il BOM dalla variabile.