Cách đơn giản để tìm kiếm tệp UTF-8 với BOM?


94

Đối với mục đích gỡ lỗi, tôi cần tìm kiếm đệ quy 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 script shell đơn giản:

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 các dòng chữ ngắn, không đọc được:

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

Nó không hoạt động với các tên tệp có dấu ngắt dòng, nhưng dù sao thì các tệp như vậy cũng 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 soạn thảo văn bản hoặc macro nào thú vị cho trình soạn thảo văn bản không?

Câu trả lời:


166

Điều gì về một 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 thích "tìm thấy" :)

Cảnh báo Ở trên sẽ sửa đổi các tệp nhị phân có chứa ba ký tự đó.

Nếu bạn chỉ muốn hiển thị tệp BOM, hãy sử dụng tệp này:

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

9
Không đúng cách phát hiện PDF với một dấu hiệu BOM .. đó là bởi vì nó tìm kiếm toàn bộ tài liệu, không chỉ là dòng đầu tiên
Olivier Refalo

1
Hoặc với ack: "ack '\ xEF \ xBB \ xBF'"
Smar

5
thay đổi lệnh sed để thêm 1 trước khi dẫn 's' vì vậy nó chỉ áp dụng cho dòng đầu tiên
Bến Combee

27
Sử dụng grep -rlI $'\xEF\xBB\xBF' .để bỏ qua các tệp nhị phân.
dbernard

1
Phát hiện và sửa đổi JPG và các tệp nhị phân khác, như đã nói.
Jehy

41

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

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

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


4
Tốt, đặc biệt là việc sử dụng Total chỉ huy yêu thích từ lâu của tôi, nhưng tiếc là điều này cũng gặp phải vấn đề giống như nhiều người khác: nó tìm kiếm tất cả các byte trong một thời gian ngắn, rất nhiều hình ảnh, v.v. đượ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ó tệp có BOM giữa chừng tệp (mặc dù phải có ít) và tất nhiên bất kỳ tệp nhị phân nào xảy ra có mã biểu đồ dòng mới ascii chỉ cần bỏ qua 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

13
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 kiểm tra nhiều hơn dòng đầu tiên của tệp, ngay cả khi một số (chẳng hạn như giải pháp của Marcus) sau đó 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 phần sau trên Linux (RHEL6) -find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
Olivier Refalo.

Làm cách nào để sửa đổi mã của bạn để sửa các tệp này sau khi chúng được tìm thấy?
Đen

7

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

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

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 xảy ra bắt đầu từ byte đầu tiên của tệp.


5

Bạn có thể sử dụng grepđể tìm chúng và Perl để tách chúng ra như vậy:

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

Điều này một 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ột máy Mac)
mjsarfatti

4

Đối với người dùng Windows, hãy xem phần này (tập lệnh PHP tốt để tìm kiếm BOMtrong dự án của bạn).


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

cùng kịch bản cũng có sẵn trong github: github.com/emrahgunduz/BomCleaner
emrahgunduz

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

Và BOM Finder: github.com/svn2github/wikia/blob/master/extensions/FCKeditor/… (trong trường hợp ai đó không thích dọn dẹp 'tự động' hoặc chỉ muốn tìm các tệp bằng BOM)
meloniq

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 vicông cụ có cùng tên), đặc biệt tìm kiếm các tập lệnh PHP:

phptags --warn ./

Sẽ xuất ra một cái gì đó như:

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

--whitespacechế độ sẽ tự động khắc phục các vấn đề như vậy (một cách đệ quy, nhưng khẳng định rằng nó chỉ viết lại các tập lệnh .php.)


2
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 đặt null \ 0 giữa mỗi tên tệp thay vì sử dụng các dòng mới
  • xargs -0 mong đợi các đối số được phân tách bằng rỗng thay vì được phân tách bằng dòng
  • grep -l liệt kê các tệp phù hợp với regex
  • Regex ^\xeff\xbb\xbfkhông hoàn toàn chính xác, vì nó sẽ khớp với các tệp UTF-8 không phải BOMed nếu chúng không có khoảng trắng chiều rộng ở đầu dòng

Bạn vẫn cần một "người đứng đầu 1" trong đường ống trước khi grep
MSalters

2

Tôi đã sử dụng điều này để chỉ sửa các tệp JavaScript:

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

0

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

file *.php | grep UTF

Điều đó sẽ không hoạt động đệ quy mặc dù. Bạn có thể tìm kiếm một số lệnh ưa thích để làm cho nó đệ quy, nhưng tôi chỉ tìm kiếm từng cấp độ riêng lẻ như sau, cho đến khi tôi hết cấp độ.

file */*.php | grep UTF
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.