2008-10-15 16 views
78

Vì mục đích gỡ lỗi, tôi cần đệ quy tìm kiếm một thư mục cho tất cả các tệp bắt đầu bằng dấu thứ tự byte UTF-8 (BOM). giải pháp hiện tại của tôi là một kịch bản đơn giản:Cách thanh lịch để tìm kiếm tệp UTF-8 bằng BOM?

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

Hoặc, nếu bạn thích ngắn, không thể đọc được một lớp lót:

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

Nó không làm việc với tên tệp chứa một ngắt dòng, nhưng các tệp như vậy sẽ không được mong đợi.

Có giải pháp nào ngắn hơn hoặc thanh lịch hơn không?

Có trình chỉnh sửa văn bản thú vị hoặc macro nào cho trình chỉnh sửa văn bản không?

Trả lời

138

Điều gì về lệnh đơn giản này không chỉ tìm thấy mà còn xóa BOM khó chịu? :)

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

tôi yêu "tìm" :)

Warning trên sẽ sửa đổi tập tin nhị phân có chứa những ba nhân vật.

.

Nếu bạn muốn chỉ hiển thị tập tin BOM, sử dụng cái này:

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

Brilliant, sir ... cảm ơn bạn! :-) – KyleFarris

+7

Phát hiện PDF không chính xác bằng dấu BOM .. đó là do nó tìm kiếm toàn bộ tài liệu, không chỉ dòng đầu tiên –

+8

Sửa đổi tệp nhị phân ... –

7

Nếu bạn chấp nhận một số dương tính giả (trong trường hợp có file phi văn bản, hoặc trong trường hợp không có một ZWNBSP ở giữa một tập tin), bạn có thể sử dụng grep:

fgrep -rl `echo -ne '\xef\xbb\xbf'` . 
2
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /' 
  • find -print0 đặt một null \ 0 giữa mỗi tên tập tin thay vì sử dụng dòng mới
  • xargs -0 hy vọng Null lập luận tách thay vì dòng tách
  • grep -l liệt kê các tập tin mà phù hợp với regex
  • Các regex ^\xeff\xbb\xbf là không hoàn toàn đúng, vì nó sẽ phù hợp với không BOMed file UTF-8 nếu họ có không gian rộng vào lúc bắt đầu của một dòng
+0

Bạn vẫn cần "đầu 1" trong ống trước grep – MSalters

5

tôi sẽ sử dụng một cái gì đó như:

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

Điều này sẽ đảm bảo rằng BOM bắt đầu ở byte đầu tiên của tệp.

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

Hầu hết các giải pháp đưa ra ở trên thử nghiệm hơn dòng đầu tiên của file, ngay cả khi một số (ví dụ như của Marcus giải pháp) rồi lọc kết quả. Giải pháp này chỉ kiểm tra dòng đầu tiên của mỗi tệp, vì vậy nó sẽ nhanh hơn một chút.

+1

Got đang làm việc với những điều sau trên Linux (RHEL6) - 'find.-type f -print0 | xargs -0 awk '/^\ xEF \ xBB \ xBF/{in FILENAME} {nextfile}' ' –

32

Cách tốt nhất và dễ nhất để thực hiện điều này trên Windows:

Total Commander → đi đến thư mục gốc của dự án → tìm file (Alt + F7) → loại tập tin * * → Tìm văn bản "EF BB. BF" hộp kiểm → kiểm tra 'Hex' → tìm kiếm

Và bạn nhận được danh sách :)

+1

Tốt, đặc biệt là việc sử dụng lệnh Tổng số yêu thích của tôi trong thời gian dài, nhưng tiếc là điều này cũng gặp vấn đề tương tự như nhiều người khác: nó tìm kiếm tất cả các byte trong một fle, rất nhiều hình ảnh vv được báo cáo. Điều này có thể được cải thiện một chút bằng cách sử dụng RegEx thay vì Hex và tìm kiếm "^ \ xEF \ xBB \ xBF" sẽ loại bỏ nhiều hình ảnh nhưng vẫn có các tệp có BOM nửa chừng tệp (mặc dù có ít nhất) và tất nhiên bất kỳ tập tin nhị phân nào xảy ra để có một mã vạch ascii newline chỉ beofre BOM. Tuy nhiên, tất cả hình ảnh đã biến mất trong tìm kiếm thử nghiệm của tôi. – Legolas

4

Đối với một Người dùng Windows, xem this (tập lệnh PHP tốt để tìm kiếm BOM trong dự án của bạn).

+0

Trang web được liên kết hiển thị: "Trang web ngoại tuyến, Không có phiên bản được lưu trong bộ nhớ cache". – vog

+0

cùng một tập lệnh cũng có sẵn trong github: http://github.com/emrahgunduz/BomCleaner – emrahgunduz

+0

Cảm ơn bạn, câu trả lời của bạn đã lưu ngày của tôi. –

3

Một giải pháp quá mức cần thiết cho điều này là phptags (không phải là công cụ vi có cùng tên), trong đó đặc biệt là tìm kiếm các kịch bản PHP:

phptags --warn ./ 

đầu ra Will cái gì đó như:

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

Và Chế độ --whitespace sẽ tự động khắc phục các sự cố đó (đệ quy, nhưng khẳng định rằng nó chỉ ghi đè các tập lệnh .php.)

2

Tôi sử dụng này để sửa chữa chỉ file JavaScript:

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

Bạn có thể sử dụng grep để tìm thấy chúng và Perl dải những người ấy như vậy:

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

Điều này làm việc cho tôi, câu trả lời được chấp nhận không (tôi đang ở trên máy Mac) – mjsarfatti

0

Nếu bạn đang tìm kiếm cho các tập tin UTF, các file command công trinh. Nó sẽ cho bạn biết mã hóa của tập tin là gì. Nếu có bất kỳ ký tự không phải ASCII nào trong đó, nó sẽ xuất hiện với UTF.

file *.php | grep UTF 

Điều đó sẽ không hoạt động theo cách đệ quy. Bạn có lẽ có thể dựng lên một số lệnh lạ mắt để làm cho nó đệ quy, nhưng tôi chỉ tìm kiếm mỗi cấp riêng như sau, cho đến khi tôi chạy ra khỏi các cấp.

file */*.php | grep UTF 
Các vấn đề liên quan