2013-05-26 33 views
34

Làm cách nào để biết tệp có phải là tệp nhị phân không?Cách kiểm tra xem tệp có phải là tệp nhị phân và đọc tất cả các tệp không phải là tệp không?

Ví dụ: tệp c đã biên dịch.

Tôi muốn đọc tất cả các tệp từ một số thư mục, nhưng tôi muốn bỏ qua các tệp nhị phân.

+8

Cuối cùng * tất cả * tệp là nhị phân. Các tệp văn bản chỉ xảy ra để chứa các biểu diễn nhị phân của dữ liệu ký tự có thể đọc được. Không có phương pháp phân biệt văn bản nào không phải là văn bản có thể đáng tin cậy 100%. –

+0

[Tương tự trong Vim.] (Http://vi.stackexchange.com/q/3206/467) – kenorb

Trả lời

35

Sử dụng tiện ích file, sử dụng mẫu:

$ file /bin/bash 
/bin/bash: Mach-O universal binary with 2 architectures 
/bin/bash (for architecture x86_64): Mach-O 64-bit executable x86_64 
/bin/bash (for architecture i386): Mach-O executable i386 

$ file /etc/passwd 
/etc/passwd: ASCII English text 

$ file code.c 
code.c: ASCII c program text 

file manual page

+4

Cân nhắc sử dụng 'file --mine'. Đối với các tệp nhị phân, nó báo cáo "... charset = binary", vì vậy có thể chỉ đơn giản là grep cho regexp "binary $". – 4dan

+8

@ 4dan - có lẽ là '--mime'? :) – Bach

+0

@ 4dan Làm việc cho tôi: 'file -bL --mime" $ ​​path "| grep -q '^ text''. Tùy chọn '-b' loại bỏ tên tập tin khỏi đầu ra, và' -L' dereferences symlinks. – wjandrea

8

Phỏng theo excluding binary file

find . -exec file {} \; | grep text | cut -d: -f1 
+0

Đây phải là 'văn bản grep'; trong lịch sử, 'file' không phải lúc nào cũng nói ASCII, mà là" shell script text "chẳng hạn. – Jens

+0

@Jens Cảm ơn bạn đã nhắc nhở. Chỉ cần kiểm tra manpage 'file', nó phải là' text'. – gongzhitaao

+0

Tôi vừa nhận ra rằng phát minh lại bánh xe một lần nữa: cho tệp trong 'tìm. -tập tin f -exec {} \; | grep text | perl -nle 'split /: /; in $ _ [0]' '; làm grep -i --color 'string_to_search' $ file; làm xong ; –

2

Sử dụng Perl tích hợp trong điều hành thử nghiệm -T tập tin, tốt nhất là sau việc xác rằng nó là một tệp đơn giản bằng cách sử dụng toán tử kiểm tra tệp -f:

$ perl -le 'for (@ARGV) { print if -f && -T }' \ 
    getwinsz.c a.out /etc/termcap /bin /bin/cat \ 
    /dev/tty /usr/share/zoneinfo/UTC /etc/motd 
getwinsz.c 
/etc/termcap 
/etc/motd 

Đây là sự bổ sung của bộ rằng:

$ perl -le 'for (@ARGV) { print unless -f && -T }' \ 
    getwinsz.c a.out /etc/termcap /bin /bin/cat \ 
    /dev/tty /usr/share/zoneinfo/UTC /etc/motd 
a.out 
/bin 
/bin/cat 
/dev/tty 
/usr/share/zoneinfo/UTC 
3
perl -E 'exit((-B $ARGV[0])?0:1);' file-to-test 

thể được sử dụng để kiểm tra bất cứ khi nào "tập tin-to-test" là nhị phân. Lệnh trên sẽ thoát đang wit 0 trên các tập tin nhị phân, nếu không thì mã số xuất cảnh sẽ là 1.

Vui lòng cung ngược lại cho tập tin văn bản có thể trông giống như lệnh sau:

perl -E 'exit((-T $ARGV[0])?0:1);' file-to-test 

Tương tự lệnh trên sẽ thoát với trạng thái 0 nếu "tệp-to-test" là văn bản (không phải nhị phân).

Đọc thêm về các kiểm tra -B-T bằng cách sử dụng lệnh perldoc -f -X.

+0

http://perldoc.perl.org/functions/-X.html – Onlyjob

0

Đó là loại lực lượng vũ phu để loại trừ tệp nhị phân với tr -d "[[:print:]\n\t]" < file | wc -c, nhưng cũng không có phỏng đoán phỏng đoán.

find . -type f -maxdepth 1 -exec /bin/sh -c ' 
    for file in "[email protected]"; do 
     if [ $(LC_ALL=C LANG=C tr -d "[[:print:]\n\t]" < "$file" | wc -c) -gt 0 ]; then 
     echo "${file} is no ASCII text file (UNIX)" 
     else 
     echo "${file} is ASCII text file (UNIX)" 
     fi 
    done 
' _ '{}' + 

Phương pháp tiếp cận vũ phu sau đây có vẻ hơi nhanh hơn một chút.

find . -type f -maxdepth 1 -exec /bin/sh -c ' 
    tab="$(printf "\t")" 
    for file in "[email protected]"; do 
     if LC_ALL=C LANG=C grep -a -m 1 "[^[:print:]${tab}]" "$file" 1>/dev/null 2>&1; then 
     echo "${file} is no ASCII text file (UNIX)" 
     else 
     echo "${file} is ASCII text file (UNIX)" 
     fi 
    done 
' _ '{}' + 
1

Hãy thử dòng lệnh sau:

file "$FILE" | grep -vq 'ASCII' && echo "$FILE is binary" 
+0

Đẹp nhưng bị lừa bởi tệp ascii urt8. Tôi đã sử dụng: file "$ FILE" | grep -vq 'văn bản' –

6

tôi sử dụng

! grep -qI . $path 

chỉ có nhược điểm tôi có thể thấy là nó sẽ xem xét một file nhị phân rỗng nhưng sau đó một lần nữa, những người quyết định nếu điều đó sai?

3

giải pháp Không lý tưởng, nhưng đơn giản để kiểm tra một tập tin duy nhất:

grep -q "\x00" file.bin && echo Binary file. || echo Text file. 

Mà về cơ bản kiểm tra nếu tập tin bao gồm ký tự NUL.

Vì vậy, để đọc tất cả các file không nhị phân đệ quy sử dụng find tiện ích bạn có thể làm:

find . -type f -exec sh -c 'grep -q "\x00" {} || cat {}' ";" 

Hoặc thậm chí đơn giản chỉ sử dụng grep:

grep -rv "\x00" . 

Đối với thư mục chỉ hiện tại, sử dụng:

grep -v "\x00" * 
1

Tắt Bach's suggestion, tôi nghĩ --mime-encoding là cờ tốt nhất để nhận được nội dung đáng tin cậy từ file.

file --mime-encoding [FILES ...] | grep -v '\bbinary$' 

sẽ in các tệp mà file tin là mã hóa không phải nhị phân. Bạn có thể đặt đầu ra này qua cut -d: -f1 để cắt : encoding nếu bạn chỉ muốn tên tệp.

Các vấn đề liên quan