Odpowiedzi:
Chociaż poprosiłeś o znalezienie BOM, użycie file
może nawet dać wyniki, gdy taka LM nie jest obecna. Od man file
:
Jeśli plik nie pasuje do żadnego z wpisów w pliku magicznym, jest sprawdzany, czy nie jest plikiem tekstowym. ASCII, ISO-8859-x, 8-bitowe zestawy znaków rozszerzonych ASCII bez ISO (takie jak używane w systemach Macintosh i IBM PC), kodowanie Unicode kodowane w UTF-8, kodowanie Unicode w kodowaniu UTF-16 i zestawy znaków EBCDIC można wyróżnić różnymi zakresami i sekwencjami bajtów, które stanowią tekst do druku w każdym zestawie. Jeśli plik przejdzie którykolwiek z tych testów, raportowany jest jego zestaw znaków.
Stąd na przykład:
odnaleźć . -type f -exec plik --mime {} | grep "charset = utf-16"
Możesz użyć grep
:
grep -rl $(echo -ne '^\0376\0377') *
(Testowane z bash
i GNU grep, może współpracować z innymi.)
Wyjaśnienie:
Część $ (echo ... generuje BOM (Hex FE FF, jako ósemkowe sekwencje ucieczki), jest następnie podawana grep
jako wzorzec, poprzedzony '^' (= początek dopasowania linii).
-r to wyszukiwanie rekurencyjne, -l sprawia, że grep wypisuje nazwy znalezionych plików (zamiast dopasowanej linii).
Może to być trochę marnotrawne, ponieważ grep całkowicie skanuje każdy plik, a nie tylko początek. Jeśli to głównie małe pliki tekstowe, nie ma to znaczenia. Jeśli masz mnóstwo plików z kilkoma MB, będziesz musiał napisać skrypt perla :-).
Alternatywnie możesz spróbować file
(w połączeniu z find + xargs). file
zidentyfikuje UTF-16 (jako „dane znaków Unicode UTF-16”). Nie wiem jednak, jak to jest niezawodne (ponieważ wykorzystuje heurystykę).
Oto skrypt, którego używam do znajdowania plików UTF-16, a następnie konwertowania ich na UTF-8. #! / bin / sh
find ./ -type f |
while read file; do
if [ "`head -c 2 -- "$file"`" == $'\xff\xfe' ]
then
echo "Problems with: $file"
# If you want to convert to UTF-8 uncomment these lines.
#cat "$file" | iconv -f UTF-16 -t UTF-8 > "$file.tmp"
#mv -f "$file.tmp" "$file"
fi
done
Jeśli go masz, możesz użyć enca
:
enca -L none * 2>/dev/null | grep -i "Universal character"
Dzięki za pomoc wszystkim. To, co działało najlepiej na moim Macu, to:
find . -type f -exec awk -F '\n' '/^\xFE\xFF|\xFF\xFE/ { print FILENAME; nextfile } { nextfile }' {} \;
Opiera się na rozwiązaniu sleske, ale bierze pod uwagę, że znak kolejności bajtów można odwrócić. Używa również awk, aby przestać szukać BOM po pierwszej linii, ponieważ BOM musi znajdować się na początku pliku. E ucieczka używana do określenia BOM działa z bash, nie wiem, czy działa z innymi powłokami.
Narzędzie enca zaproponowane przez ghostdog74 również wykona zadanie, ale nie było go na moim Macu.
-l
sprawia, żegrep
zatrzymuje się na pierwszym wystąpieniu. Z-I
jednym powoduje równieżgrep
ignorowanie plików binarnych.