BOM ile UTF-8 dosyalarını aramanın zarif yolu?


94

Hata ayıklama amacıyla, UTF-8 bayt sıra işareti (BOM) ile başlayan tüm dosyalar için yinelemeli olarak bir dizinde arama yapmam gerekiyor. Mevcut çözümüm basit bir kabuk betiğidir:

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

Veya, kısa, okunamayan tek satırlı yazıları tercih ediyorsanız:

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

Satır sonu içeren dosya adlarıyla çalışmaz, ancak bu tür dosyaların yine de beklenmemesi gerekir.

Daha kısa veya daha zarif bir çözüm var mı?

Metin düzenleyiciler için ilginç metin düzenleyicileri veya makrolar var mı?

Yanıtlar:


166

Peki ya iğrenç ürün reçetesini bulup temizleyen bu basit komut? :)

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

"Bulmayı" seviyorum :)

Uyarı Yukarıdakiler, bu üç karakteri içeren ikili dosyaları değiştirecektir .

Yalnızca BOM dosyalarını göstermek istiyorsanız, bunu kullanın:

grep -rl $'\xEF\xBB\xBF' .

9
PDF'yi bir ürün reçetesi işaretleyiciyle yanlış bir şekilde algılar .. bunun nedeni yalnızca ilk satırı değil, tüm belgeyi
aramasıdır

1
Veya ack ile: "ack '\ xEF \ xBB \ xBF'"
Smar

5
sed komutunu baştaki 's'den önce 1 eklemek için değiştirin, böylece yalnızca ilk satıra uygulanır
Ben Combee

27
grep -rlI $'\xEF\xBB\xBF' .İkili dosyaları yok saymak için kullanın .
dbernard

1
Daha önce söylendiği gibi JPG ve diğer ikili dosyaları algılar ve değiştirir.
Jehy

41

Bunu Windows'ta yapmanın en iyi ve en kolay yolu:

Total Commander → projenin kök dizinine git → dosyaları bul ( Alt+ F7) → dosya türleri *. * → "EF BB BF" metnini bul → 'Hex' onay kutusunu işaretleyin → ara

Ve listeyi aldın :)


4
Güzel, özellikle uzun zamandır en sevdiğim Total komutanımın kullanımı, ama ne yazık ki bu, diğerleri ile aynı sorunu yaşıyor: bir dosyadaki tüm baytları arar, pek çok resim vb. Bu, Hex yerine RegEx kullanılarak ve "^ \ xEF \ xBB \ xBF" araması yapılarak biraz iyileştirilebilir; bu, birçok görüntüyü ortadan kaldıracak, ancak yine de BOM'u dosyanın ortasında bulunan dosyalara sahiptir (çok az olması gerekir) ve tabii ki bir ascii satırsonu karakter koduna sahip olan herhangi bir ikili dosya, ürün reçetesinden daha önce. Yine de, test aramamda tüm görüntüler gitmişti.
Legolas

13
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

Yukarıda verilen çözümlerin çoğu, bazıları (Marcus'un çözümü gibi) sonuçları filtrelese bile, dosyanın ilk satırından daha fazlasını test eder. Bu çözüm, her dosyanın yalnızca ilk satırını test eder, bu nedenle biraz daha hızlı olması gerekir.


1
Got, Linux (RHEL6) üzerinde aşağıdakilerle çalışıyor -find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
Olivier Refalo

Bu dosyaları bulunduktan sonra düzeltmek için kodunuzu nasıl değiştirmeliyim?
Siyah

7

Bazı yanlış pozitifleri kabul ederseniz (metin olmayan dosyalar olması veya olası olmayan bir durumda bir dosyanın ortasında bir ZWNBSP olması durumunda), grep'i kullanabilirsiniz:

fgrep -rl `echo -ne '\xef\xbb\xbf'` .

5

Şunun gibi bir şey kullanırım:

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

Bu, BOM'nin dosyanın ilk baytından başlayarak gerçekleşmesini sağlar.


5

grepOnları bulmak için ve Perl'i bu şekilde çıkarmak için kullanabilirsiniz :

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'

Bu benim için çalıştı, kabul edilen cevap olmadı (Mac kullanıyorum)
mjsarfatti


3

Özellikle PHP betiklerini arayan (aynı ada sahip bir araç phptagsdeğil) buna aşırı bir çözüm vi:

phptags --warn ./

Şöyle bir çıktı verecektir:

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

Ve --whitespacekip bu tür sorunları otomatik olarak düzeltir (yinelemeli olarak, ancak yalnızca .php komut dosyalarını yeniden yazdığını iddia eder.)


2
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 yeni satırlar kullanmak yerine her dosya adı arasına bir null \ 0 koyar
  • xargs -0 satırla ayrılmış yerine boş değerle ayrılmış argümanlar bekler
  • grep -l normal ifade ile eşleşen dosyaları listeler
  • ^\xeff\xbb\xbfBir satırın başında sıfır genişlik boşlukları varsa BOMed olmayan UTF-8 dosyalarıyla eşleşeceği için normal ifade tamamen doğru değildir


2

Bunu yalnızca JavaScript dosyalarını düzeltmek için kullandım:

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;

0

UTF dosyalarını arıyorsanız, dosya komutu çalışır. Dosyanın kodlamasının ne olduğunu size söyleyecektir. İçinde ASCII olmayan karakterler varsa, UTF ile gelecektir.

file *.php | grep UTF

Yine de yinelemeli çalışmaz. Bunu yinelemeli yapmak için muhtemelen bazı süslü komutlar kurabilirsiniz, ancak seviyelerim bitene kadar her seviyeyi aşağıdaki gibi ayrı ayrı aradım.

file */*.php | grep UTF
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.