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?

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' .

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ę :)


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.


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'` .

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.


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}{}'

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).


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).


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

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 \;

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.