Elegancki sposób wyszukiwania plików UTF-8 za pomocą BOM?

94

Do celów debugowania muszę rekurencyjnie przeszukiwać katalog dla wszystkich plików, które zaczynają się od znacznika kolejności bajtów UTF-8 (BOM). Moje obecne rozwiązanie to prosty skrypt powłoki:

find -type f |
while read file
do
    if [ "`head -c 3 -- "$file"`" == $'\xef\xbb\xbf' ]
    then
        echo "found BOM in: $file"
    fi
done

Lub, jeśli wolisz krótkie, nieczytelne jednowierszowe:

find -type f|while read file;do [ "`head -c3 -- "$file"`" == $'\xef\xbb\xbf' ] && echo "found BOM in: $file";done

Nie działa z nazwami plików, które zawierają podział wiersza, ale takich plików i tak nie należy się spodziewać.

Czy jest jakieś krótsze lub bardziej eleganckie rozwiązanie?

Czy są jakieś interesujące edytory tekstu lub makra do edytorów tekstu?

vog
źródło

Odpowiedzi:

166

A co z tym jednym prostym poleceniem, które nie tylko wyszukuje, ale usuwa okropne zestawienie komponentów? :)

find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;

Uwielbiam „znajdowanie” :)

Ostrzeżenie Powyższe zmodyfikuje pliki binarne, które zawierają te trzy znaki.

Jeśli chcesz tylko pokazać pliki BOM, użyj tego:

grep -rl $'\xEF\xBB\xBF' .
Denis
źródło
9
Nieprawidłowo wykrywa PDF ze znacznikiem BOM ... to dlatego, że przeszukuje cały dokument, a nie tylko pierwszą linię
Olivier Refalo
1
Lub z potwierdzeniem: „ACK '\ xEF \ xBB \ xBF'”
Smar
5
zmień polecenie sed, aby dodać 1 przed wiodącym
``
27
Służy grep -rlI $'\xEF\xBB\xBF' .do ignorowania plików binarnych.
dbernard
1
Wykrywa i modyfikuje pliki JPG i inne pliki binarne, jak już powiedziano.
Jehy
41

Najlepszy i najłatwiejszy sposób na zrobienie tego w systemie Windows:

Total Commander → przejdź do katalogu głównego projektu → znajdź pliki ( Alt+F7 ) → typy plików *. * → Znajdź tekst „EF BB BF” → zaznacz pole wyboru „Hex” → szukaj

I dostajesz listę :)

Jan Przybyło
źródło
4
Fajnie, zwłaszcza gdy używam mojego ulubionego Total Commander, ale niestety cierpi na ten sam problem, co wielu innych: przeszukuje wszystkie bajty we flocie, tak wiele obrazów itp. Jest zgłaszanych. Można to nieco poprawić, używając wyrażenia regularnego zamiast szesnastkowego i wyszukując „^ \ xEF \ xBB \ xBF”, co wyeliminuje wiele obrazów, ale nadal zawiera pliki, które mają BOM w połowie pliku (chociaż powinno ich być niewiele) i oczywiście wszelkie pliki binarne, które mają kod znaku nowej linii ascii, po prostu przed BOM. Mimo to wszystkie obrazy zniknęły z mojego wyszukiwania testowego.
Legolas
13
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

Większość podanych powyżej rozwiązań testuje więcej niż pierwszy wiersz pliku, nawet jeśli niektóre (na przykład rozwiązanie Marcusa) filtrują wyniki. To rozwiązanie testuje tylko pierwszą linię każdego pliku, więc powinno być trochę szybsze.

Aron Griffis
źródło
1
Got pracuje z następującymi elementami w systemie Linux (RHEL6) -find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
Olivier Refalo
Jak mam zmodyfikować kod, aby naprawić te pliki po ich znalezieniu?
Czarny
7

Jeśli akceptujesz fałszywe alarmy (w przypadku, gdy istnieją pliki nietekstowe lub w mało prawdopodobnym przypadku w środku pliku znajduje się ZWNBSP), możesz użyć grep:

fgrep -rl `echo -ne '\xef\xbb\xbf'` .
CesarB
źródło
5

Użyłbym czegoś takiego:

grep -orHbm1 "^`echo -ne '\xef\xbb\xbf'`" . | sed '/:0:/!d;s/:0:.*//'

Co zapewni, że zestawienie komponentów zacznie się od pierwszego bajtu pliku.

Marcus Griep
źródło
5

Możesz użyć, grepaby je znaleźć i Perla, aby je rozebrać w następujący sposób:

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'
teoria
źródło
Ten zadziałał dla mnie, zaakceptowana odpowiedź nie (jestem na Macu)
mjsarfatti
4

Dla użytkownika Windows zobacz to (dobry skrypt PHP do znajdowania BOMw twoim projekcie).

julien
źródło
Połączona witryna internetowa zawiera komunikat: „Witryna offline, brak dostępnej wersji w pamięci podręcznej”.
vog,
ten sam skrypt jest również dostępny na github: github.com/emrahgunduz/BomCleaner
emrahgunduz
Dzięki kolego, Twoja odpowiedź uratowała mi dzień.
Krunal Panchal
I wyszukiwarka BOM: github.com/svn2github/wikia/blob/master/extensions/FCKeditor/… (na wypadek, gdyby ktoś nie lubił automatycznego '' czyszczenia lub po prostu chciał znaleźć pliki z BOM)
meloniq
3

Przesadnym rozwiązaniem tego problemu jest phptags(nie vinarzędzie o tej samej nazwie), które w szczególności szuka skryptów PHP:

phptags --warn ./

Wyświetli coś takiego:

./invalid.php: TRAILING whitespace ("?>\n")
./invalid.php: UTF-8 BOM alone ("\xEF\xBB\xBF")

Oraz --whitespacetryb automatycznie rozwiązać takie problemy (rekurencyjnie, ale twierdzi, że to tylko przepisuje skrypty .php).

mario
źródło
2
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 umieszcza null \ 0 między każdą nazwą pliku zamiast używać nowych linii
  • xargs -0 oczekuje argumentów oddzielonych od wartości null zamiast oddzielonych wierszami
  • grep -l wyświetla pliki, które pasują do wyrażenia regularnego
  • Wyrażenie regularne ^\xeff\xbb\xbfnie jest do końca poprawne, ponieważ będzie pasowało do plików UTF-8 bez zestawienia komponentów, jeśli mają one zerową szerokość spacji na początku wiersza
Jonathan Wright
źródło
Nadal potrzebujesz „głowy 1” w rurze przed
grepem
2

Użyłem tego do poprawienia tylko plików JavaScript:

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;
Refineo
źródło
0

Jeśli szukasz plików UTF, polecenie pliku działa. Powie ci, jakie jest kodowanie pliku. Jeśli są tam jakieś znaki spoza ASCII, pojawi się UTF.

file *.php | grep UTF

To nie zadziała jednak rekurencyjnie. Prawdopodobnie możesz skonfigurować jakieś wymyślne polecenie, aby było rekurencyjne, ale po prostu przeszukałem każdy poziom indywidualnie, tak jak poniżej, aż zabrakło mi poziomów.

file */*.php | grep UTF
Mike Dotterer
źródło