Nejprve si ukažme, že head
ve skutečnosti funguje správně:
$ printf '\xef\xbb\xbf' >file
$ head -c 3 file
$ head -c 3 file | hexdump -C
00000000 ef bb bf |...|
00000003
Nyní vytvoříme funkční funkci has_bom
. Pokud je vaše grep
podporuje -P
, pak jedna možnost je:
$ has_bom() { head -c3 "$1" | LC_ALL=C grep -qP '\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
V současné době pouze GNU grep
podporuje -P
.
Další možností je použít bash $'...'
:
$ has_bom() { head -c3 "$1" | grep -q $'\xef\xbb\xbf'; }
$ has_bom file && echo yes
yes
ksh
a zsh
také podporuje $'...'
ale tento konstrukt není POSIX a dash
to nepodporuje.
Poznámky:
-
Použití explicitního
return $?
je volitelný. Funkce se standardně vrátí s návratovým kódem posledního spuštění příkazu. -
Pro definování funkcí jsem použil formulář POSIX. To je ekvivalentní s bash formou, ale dává vám to o jeden problém méně, pokud byste někdy museli spouštět funkci pod jiným shellem.
-
bash akceptuje použití znaku
-
v názvu funkce, ale to je kontroverzní funkce. Nahradil jsem ho_
který je více akceptován. (Další informace o tomto problému naleznete v této odpovědi.) -
-q
možnost nagrep
ztiší jej, což znamená, že stále nastavuje správný výstupní kód, ale neposílá žádné znaky do stdout.
Pro první přečtený řádek jsem použil následující:
read c
if (( "$(printf "%d" "'${c:0:1}")" == 65279 )) ; then c="${c:1}" ; fi
To jednoduše odstraní kusovník z proměnné.