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
-qopzione agreplo 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.