Làm thế nào để gửi tệp văn bản có chứa một số dữ liệu nhị phân?


122

trả lại grep

Đối sánh tệp nhị phân test.log

Ví dụ

echo    "line1 re \x00\r\nline2\r\nline3 re\r\n" > test.log  # in zsh
echo -e "line1 re \x00\r\nline2\r\nline3 re\r\n" > test.log  # in bash
grep re test.log

Tôi ước kết quả sẽ hiển thị dòng1 và dòng3 (tổng hai dòng).

Có thể sử dụng trchuyển đổi dữ liệu không thể in thành dữ liệu có thể đọc được để cho phép grep hoạt động trở lại không?


Xin lưu ý rằng có một chương trình lọc ra các ký tự nhị phân từ tệp nhị phân và chỉ giữ lại các ký tự văn bản (có thể đọc được). Tại đây: soft.tahionic.com/download-words_extractor/index.html
InTheNameOfScience,

Xin lỗi, nhưng ... không phải là bạn mất tích -etrong echolệnh?
Sopalajo de Arrierez

Nếu bạn sử dụng 'zsh', không cần -e cũng được. Nếu bạn sử dụng 'bash', bạn nên thêm '-e'.
Daniel YC Lin

Câu trả lời:


67

Bạn có thể chạy tệp dữ liệu qua cat -v, ví dụ:

$ cat -v tmp/test.log | grep re
line1 re ^@^M
line3 re^M

mà sau đó có thể được xử lý hậu kỳ hơn nữa để loại bỏ rác; điều này tương tự nhất với truy vấn của bạn về việc sử dụng trcho nhiệm vụ.


5
Đã giải quyết vấn đề của tôi. Cảm ơn! Đây là những gì man catnói về -v:-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
tommy.carstensen

Lưu ý rằng điều này cũng hoạt động trong một đường ống. Ví dụ:set | cat -v | grep variable
funroll

1
Tại sao sử dụng nó nếu grep --text hoạt động? Điều này có vẻ phức tạp hơn rất nhiều.
Michael Haefele

grep --textkhông phải lúc nào cũng hoạt động; nó tôn trọng CTRL + D như một trình kết thúc tệp. Vì vậy, nếu bạn có cái đó trong tệp nhị phân của mình, grep sẽ thoát sớm.
Tommy

110
grep -a

Nó không thể trở nên đơn giản hơn thế.


3
đây là giống như grep --textpaxdiablo đã đề cập đến 2 năm trước
user829755

4
Có, ngoại trừ việc điều này sẽ không hoạt động trên OSX trừ khi bạn làm như sau:LC_ALL="C" grep -a
Chris Stratton

91

Có một cách là dù sao cũng chỉ cần coi các tệp nhị phân là văn bản, grep --textnhưng điều này cũng có thể dẫn đến thông tin nhị phân được gửi đến thiết bị đầu cuối của bạn. Đó thực sự không phải là một ý tưởng hay nếu bạn đang chạy một thiết bị đầu cuối thông dịch luồng đầu ra (chẳng hạn như VT / DEC hoặc nhiều thiết bị khác).

Ngoài ra, bạn có thể gửi tệp của mình thông qua trlệnh sau:

tr '[\000-\011\013-\037\177-\377]' '.' <test.log | grep whatever

Điều này sẽ thay đổi bất kỳ thứ gì nhỏ hơn ký tự khoảng trắng (ngoại trừ dòng mới) và bất kỳ thứ gì lớn hơn 126, thành một .ký tự, chỉ để lại các bản in.


Nếu bạn muốn mọi ký tự "bất hợp pháp" được thay thế bằng một ký tự khác, bạn có thể sử dụng một cái gì đó như chương trình C sau, một bộ lọc đầu vào tiêu chuẩn cổ điển:

#include<stdio.h>
int main (void) {
    int ch;
    while ((ch = getchar()) != EOF) {
        if ((ch == '\n') || ((ch >= ' ') && (ch <= '~'))) {
            putchar (ch);
        } else {
            printf ("{{%02x}}", ch);
        }
    }
    return 0;
}

Điều này sẽ cung cấp cho bạn {{NN}}, đâu NNlà mã hex cho ký tự. Bạn có thể chỉ cần điều chỉnh printfbất kỳ kiểu đầu ra nào bạn muốn.

Bạn có thể thấy chương trình đó đang hoạt động tại đây, trong đó:

pax$ printf 'Hello,\tBob\nGoodbye, Bob\n' | ./filterProg
Hello,{{09}}Bob
Goodbye, Bob

Phương pháp này ánh xạ tất cả các ký tự nhị phân thành cùng một '.' Biểu tượng. Có phương pháp nào khác ánh xạ chúng thành các ký hiệu có thể đọc được không?
Daniel YC Lin

Chắc chắn, bạn có thể chạy nó thông qua một chương trình lọc khác, một trong số đó tôi đã cung cấp trong bản cập nhật.
paxdiablo

1
Tôi nghĩ tr '[:cntrl:] '.'là tốt hơn. Và nó phải \000-\010\013\014\016-\037\177-\377'ở trong cú pháp tr của bạn.
Daniel YC Lin

2
Sau khi thử nghiệm, tr '[\000-\010\013\014\016-\037\177-\377]' '_'có thể hoạt động được, cntrl không phù hợp với trường hợp của tôi.
Daniel YC Lin

2
Bạn có thể lưu các catbước bằng cách grep --textđưa vào trthay vì ngược lại. Điều này cũng cho phép bạn grep nhiều tệp và giữ tham chiếu tên tệp trong đầu ra.
aaaantoine

33

Bạn có thể sử dụng "chuỗi" để trích xuất chuỗi từ tệp nhị phân, chẳng hạn

strings binary.file | grep foo

Hoạt động tốt đối với tôi vì nguồn là một nhật ký gỡ lỗi với UID trên mỗi dòng. Cảm ơn.
mbrownnyc

cũng làm việc tốt cho tôi. Cảm ơn câu trả lời của bạn. Đã lưu ngày của tôi :)
Shekhar

2
Tôi đánh giá cao câu trả lời của @paxdiablo nhưng để có câu trả lời nhanh và bắt đầu công việc, bạn không thể mắc lỗi này.
Wil

Đã thử sử dụng giải pháp paxdiablo nhưng nó không mang lại cho tôi bất kỳ kết quả nào mà tôi mong đợi. @moodywoody giải pháp của bạn nhanh chóng, đơn giản và xuất ra chính xác những gì tôi cần!
justinhartman

20

Bạn có thể buộc grep xem các tệp nhị phân với:

grep --binary-files=text

Bạn cũng có thể muốn thêm -o( --only-matching) để bạn không nhận được hàng tấn ngôn ngữ vô nghĩa nhị phân sẽ làm hỏng thiết bị đầu cuối của bạn.


có thể tạo ra rác nhị phân, có thể có các tác dụng phụ khó chịu nếu đầu ra là một thiết bị đầu cuối và nếu trình điều khiển thiết bị đầu cuối diễn giải một số nó dưới dạng lệnh.
Daniel YC Lin

Nếu bạn sử dụng --only-matchingvà regex của bạn không khớp với dữ liệu nhị phân tùy ý, bạn sẽ không gặp vấn đề gì.
AB

nếu biểu thức chính quy là 'first. * end' và dữ liệu nhị phân chứa trong mẫu '. *', thì nó không thể sửa quy trình xử lý bài đăng của tôi. Dù sao cũng cảm ơn.
Daniel YC Lin

16

Bắt đầu với Grep 2.21, các tệp nhị phân được xử lý khác nhau :

Khi tìm kiếm dữ liệu nhị phân, grep bây giờ có thể coi các byte không phải văn bản là dấu kết thúc dòng. Điều này có thể thúc đẩy hiệu suất đáng kể.

Vì vậy, những gì xảy ra bây giờ là với dữ liệu nhị phân, tất cả các byte không phải văn bản (bao gồm cả dòng mới) đều được coi là dấu cuối dòng. Nếu bạn muốn thay đổi hành vi này, bạn có thể:

  • sử dụng --text. Điều này sẽ đảm bảo rằng chỉ các dòng mới là dấu chấm hết dòng

  • sử dụng --null-data. Điều này sẽ đảm bảo rằng chỉ các byte rỗng là dấu chấm hết dòng


5

grep -a sẽ buộc grep tìm kiếm và xuất ra từ một tệp mà grep nghĩ là tệp nhị phân. grep -a re test.log



2

bạn có thể làm

strings test.log | grep -i

điều này sẽ chuyển đổi đầu ra là một chuỗi có thể đọc được thành grep.


0

Bạn cũng có thể thử công cụ Word Extractor . Word Extractor có thể được sử dụng với bất kỳ tệp nào trong máy tính của bạn để tách các chuỗi chứa văn bản / từ của con người khỏi mã nhị phân (ứng dụng exe, DLL).


Trường hợp của tôi, tôi không yêu cầu trích xuất từ, tôi yêu cầu giữ nguyên số dòng.
Daniel YC Lin

0

Đây là những gì tôi đã sử dụng trong một hệ thống chưa cài đặt lệnh "string"

cat yourfilename | tr -cd "[:print:]"

Thao tác này sẽ in văn bản và xóa các ký tự không in được trong một lần rơi, không giống như "cat -v filename", yêu cầu một số xử lý hậu kỳ để loại bỏ những thứ không mong muốn. Lưu ý rằng một số dữ liệu nhị phân có thể in được, vì vậy bạn vẫn sẽ nhận được một số thứ vô nghĩa giữa những thứ tốt. Tôi nghĩ rằng các chuỗi cũng loại bỏ những thứ vô nghĩa này nếu bạn có thể sử dụng nó.

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.