Điều gì có thể khiến lệnh tệp trong Linux báo cáo tệp văn bản dưới dạng dữ liệu?


4

Tôi có một vài tệp nguồn C ++ (một .cpp và một .h) đang được báo cáo là loại dữ liệu bằng file lệnh trong Linux. Khi tôi chạy file -bi lệnh chống lại các tệp này, tôi được cung cấp đầu ra này (cùng một đầu ra cho mỗi tệp):

application/octet-stream; charset=binary

Mỗi tệp rõ ràng là văn bản đơn giản (tôi có thể xem chúng trong vi ). Điều gì gây ra file để báo cáo sai loại tập tin này? Nó có thể là một số loại Unicode? Cả hai tệp này đều được tạo trong Windows-Land (sử dụng Visual Studio 2005), nhưng chúng đang được biên dịch trong Linux (đây là một ứng dụng đa nền tảng).

Có những câu chuyện mới trên trang chủ.

Cập nhật : Tôi không thấy bất kỳ ký tự null nào trong cả hai tệp. Tôi đã tìm thấy một số ký tự mở rộng trong tệp .cpp (trong khối nhận xét), đã xóa chúng, nhưng file vẫn báo cáo cùng mã hóa. Tôi đã thử buộc mã hóa trong SlickEdit, nhưng dường như điều đó không có tác dụng. Khi tôi mở tập tin trong vim, Tôi thấy một [converted] ngay khi tôi mở tập tin. Có lẽ tôi có thể lấy vim để buộc mã hóa?


Bất kỳ ký tự null trong chúng?
Mehrdad

Cách dễ dàng để kiểm tra null trong tệp là gì? Theo hiểu biết của tôi, họ không có bất kỳ thứ gì, nhưng điều đó không có nghĩa là một người lẻn vào đâu đó ...
Jonah Bishop

Hmm ... bạn có thể mở chúng ra Khoa học viễn tưởng và kiểm tra NUL hộp (hoặc tìm kiếm \0 với các phép biến đổi dấu gạch chéo ngược).
Mehrdad

Hãy thử 'cat -v' để hiển thị các ký tự điều khiển.
Brian Swift

Điều gì xảy ra khi bạn chạy file -e soft filename?
Daniel Beck

Câu trả lời:


4

Vim cố gắng hết sức để hiểu bất cứ điều gì bạn ném vào nó mà không phàn nàn. Điều này làm cho nó trở thành một công cụ tương đối kém để sử dụng để chẩn đoán file đầu ra.

Thông báo "[đã chuyển đổi]" của Vim cho biết có một cái gì đó trong tệp mà vim sẽ không thấy trong mã hóa văn bản được đề xuất bởi cài đặt ngôn ngữ của bạn (LANG, v.v.).

Những người khác đã đề nghị

  • cat -v
  • xxd

Bạn có thể thử grepping cho các ký tự không phải ASCII.

  • grep -P '[\x7f-\xff]' filename

Khả năng khác là kết thúc dòng không chuẩn cho nền tảng (nghĩa là CRLF hoặc CR) nhưng tôi mong đợi file để đối phó với điều đó và báo cáo "tệp văn bản DOS" hoặc tương tự.


file không làm tốt công việc phát hiện các tệp văn bản DOS
iruvar

cat -v giải quyết vấn đề của tôi cảm ơn.
RASG

3

Nếu bạn chạy file -D filename, file hiển thị thông tin gỡ lỗi, bao gồm các thử nghiệm mà nó thực hiện. Gần cuối, nó sẽ hiển thị thử nghiệm nào đã thành công trong việc xác định loại tệp.

Đối với một tệp văn bản thông thường, nó trông như thế này:

[31> 0 regex,=^package[ \t]+[0-9A-Za-z_:]+ *;,""]
1 == 0 = 0
ascmagic 1
filename.txt: ISO-8859 text, with CRLF line terminators

Điều này sẽ cho bạn biết những gì nó tìm thấy để xác định đó là loại mime.


Tôi không thấy tùy chọn -D trong cài đặt tệp của mình (v5.04) ...
Jonah Bishop

Hãy thử -d thay thế. Nó hoạt động với tệp-5.03 như được cài đặt trên Fedora 11.
garyjohn

Thông báo cho @JonahBishop về bình luận của garyjohn. Bài viết của tôi đã được viết cho file được bao gồm trong OS X. Debian 6 của tôi không có -d cũng không -D Tuy nhiên...
Daniel Beck

Cờ -d hoạt động với tôi, nhưng có quá nhiều đầu ra Tôi không chắc nên tìm gì ...
Jonah Bishop

3

Tôi tìm thấy vấn đề bằng cách sử dụng tìm kiếm nhị phân để xác định vị trí các dòng có vấn đề.

head -n {1/2 line count} file.cpp > a.txt
tail -n {1/2 line count} file.cpp > b.txt

Đang chạy file chống lại mỗi nửa và lặp lại quá trình, giúp tôi xác định vị trí đường vi phạm. Tôi tìm thấy Control + P ( ^P ) ký tự được nhúng trong nó. Loại bỏ nó đã giải quyết vấn đề. Tôi sẽ tự viết một kịch bản Perl để tìm kiếm các nhân vật này (và các phần mở rộng khác) trong tương lai.

Một lời cảm ơn lớn cho tất cả mọi người đã cung cấp một câu trả lời cho tất cả các lời khuyên!


0

có thể có phải là các tệp đã được lưu bằng BOM khi bắt đầu chúng, mặc dù tôi đã nghĩ rằng một phiên bản nhị phân gần đây của tệp nhị phân cũng sẽ nhận ra điều đó.

Bạn đã thử vứt chúng qua một cái gì đó như "đầu -2 | xxd" và xem liệu có BOM không?

* BOM = Dấu thứ tự Byte - đôi khi có trong tệp văn bản unicode. http://en.wikipedia.org/wiki/Byte_order_mark


Đó là một mẹo thú vị. Tôi đã chạy cả hai tệp qua xxd và tôi không thấy BOM ở vị trí ký tự đầu tiên. Mỗi tệp bắt đầu với một khối nhận xét khổng lồ, vì vậy tôi thấy một loạt các dấu gạch chéo để bắt đầu.
Jonah Bishop

Muốn chia sẻ một đoạn trích?
GodEater

Đây là những gì tôi thấy từ kết xuất xxd: 0000000: 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f 2f2f ////////////////
Jonah Bishop

0

Nó có thể là một ký tự không phải ASCII từ Unicode hoặc một số bộ ký tự khác. Vì bạn đang sử dụng vi, trong hầu hết các bản phân phối Linux là một số phiên bản của vim, bạn có thể tìm kiếm nhân vật đó bằng cách gõ

/[<Ctrl-V>x80-<Ctrl-V>xff]

và nhấn Enter, ở đâu <Ctrl-V> có nghĩa là gõ v trong khi nhấn Ctrl Chìa khóa. Tương tự, bạn có thể tìm kiếm null (như Mehrdad đề xuất) với điều này:

/<Ctrl-V>x00

Tìm kiếm này dẫn đến một khối nhận xét có chứa một số ký tự mở rộng trong tệp .cpp của tôi. Tuy nhiên, tôi không thấy bất kỳ nhân vật tương tự nào trong .h ...
Jonah Bishop

Tôi đã cập nhật câu trả lời của mình để bao gồm tìm kiếm null như Mehrdad đề xuất.
garyjohn

Tôi không thấy bất kỳ ký tự null nào trong cả hai tập tin. :
Jonah Bishop

0

Bộ ký tự / mã hóa / (codepage) nào là các tệp trong?
Có lẽ các tập tin có nhân vật đi lạc. thường là từ mã hóa chéo xấu giữa các nền tảng khác nhau. Dữ liệu không hợp lệ trong tệp của bạn có thể gây ra file để báo cáo như bạn đã mô tả. Bạn có thể kiểm tra tính hợp lệ của một tệp để mã hóa bộ ký tự cụ thể bằng cách kiểm tra nó với recode (hoặc là iconv ).

Theo liên kết để có danh sách Mã hóa ký tự phổ biến

Kịch bản này liệt kê các bảng mã ký tự (từ $my_csets ) không hợp lệ cho (các) tệp của bạn. Bạn có thể liệt kê tất cả các bộ ký tự thông qua: recode -l

file="$1"    
my_csets="UTF-16 UTF-8 windows-1250 ASCII"

# Use the next lines to test all charsets
# =======================================
# all_csets=$(recode -l |sed -ne "/^[^:/]/p" | awk '{print $1}')
# my_csets=$all_csets

for cset in $my_csets ;do 
  <"$1" recode $cset.. &>/dev/null || echo  "$cset  ERROR: $?"
done 
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.