Lassen Sie uns zuerst diesen head
demonstrieren funktioniert eigentlich richtig:
$ printf '\xef\xbb\xbf' >file
$ head -c 3 file
$ head -c 3 file | hexdump -C
00000000 ef bb bf |...|
00000003
Lassen Sie uns nun eine funktionierende Funktion has_bom
erstellen . Wenn Ihr grep
unterstützt -P
, dann ist eine Option:
$ has_bom() { head -c3 "$1" | LC_ALL=C grep -qP '\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
Derzeit nur GNU grep
unterstützt -P
.
Eine weitere Option ist die Verwendung von $'...'
von bash :
$ has_bom() { head -c3 "$1" | grep -q $'\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
ksh
und zsh
unterstützt auch $'...'
aber dieses Konstrukt ist nicht POSIX und dash
unterstützt es nicht.
Hinweise:
-
Die Verwendung eines expliziten
return $?
es ist optional. Die Funktion kehrt standardmäßig mit dem Exit-Code der letzten Befehlsausführung zurück. -
Ich habe das POSIX-Formular zum Definieren von Funktionen verwendet. Dies entspricht dem Bash-Formular, gibt Ihnen aber ein Problem weniger, mit dem Sie sich auseinandersetzen müssen, wenn Sie die Funktion jemals unter einer anderen Shell ausführen müssen.
-
bash akzeptiert die Verwendung des Zeichens
-
in einem Funktionsnamen, aber dies ist ein umstrittenes Merkmal. Ich habe es durch_
ersetzt was mehr akzeptiert wird. (Weitere Informationen zu diesem Thema finden Sie in dieser Antwort.) -
Die
-q
Option zugrep
macht es leise, was bedeutet, dass es immer noch einen richtigen Exit-Code setzt, aber es sendet keine Zeichen an stdout.
Für die erste Lesezeile habe ich Folgendes angewendet:
read c
if (( "$(printf "%d" "'${c:0:1}")" == 65279 )) ; then c="${c:1}" ; fi
Dadurch wird einfach die Stückliste aus der Variablen entfernt.