바이너리 데이터가 포함 된 텍스트 파일을 grep하는 방법은 무엇입니까?


122

grep 반환

바이너리 파일 test.log 일치

예를 들면

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

결과에 line1과 line3 (총 2 줄)이 표시되기를 바랍니다.

trgrep이 다시 작동하도록 인쇄 할 수없는 데이터를 읽을 수있는 데이터로 변환하는 것이 가능 합니까?


바이너리 파일에서 바이너리 문자를 걸러 내고 텍스트 문자 (읽기 가능) 만 유지하는 프로그램이 있습니다. 여기 : soft.tahionic.com/download-words_extractor/index.html
InTheNameOfScience

실례 합니다만 ... 사령부 -e에서 누락되지 않았 echo나요?
Sopalajo de Arrierez 2014

'zsh'를 사용하면 -e 없이도 괜찮습니다. 'bash'를 사용하는 경우 '-e'를 추가해야합니다.
Daniel YC Lin

답변:


67

를 통해 데이터 파일을 실행할 수 있습니다. cat -v예 :

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

그런 다음 정크를 제거하기 위해 추가 후 처리 될 수 있습니다. 이것은 tr작업 에 대한 사용에 대한 쿼리와 가장 유사합니다 .


5
내 문제를 해결했습니다. 감사! 여기에 대해 man cat말한다 -v:-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
tommy.carstensen

이것은 파이프 라인에서도 작동합니다. 예set | cat -v | grep variable
funroll

1
grep --text가 작동한다면 왜 이것을 사용합니까? 이것은 훨씬 더 복잡해 보입니다.
Michael Haefele

grep --text항상 작동하지는 않습니다. CTRL + D를 파일 종결 자로 간주합니다. 따라서 바이너리 파일에있는 경우 grep이 일찍 종료됩니다.
Tommy


91

한 가지 방법은 이진 파일을 텍스트로 간단히 처리하는 grep --text것이지만 이로 인해 이진 정보가 터미널로 전송 될 수 있습니다. 출력 스트림 (VT / DEC 등)을 해석하는 터미널을 실행하는 경우에는 실제로 좋은 생각이 아닙니다.

또는 tr다음 명령 을 사용 하여 파일을 보낼 수 있습니다 .

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

이것은 공백 문자 (개행 제외)보다 작은 문자와 126보다 큰 .문자를 문자 로 변경 하여 인쇄 가능 항목 만 남깁니다.


모든 "불법"문자를 다른 문자로 바꾸려면 다음 C 프로그램과 같은 고전적인 표준 입력 필터를 사용할 수 있습니다.

#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;
}

이것은 당신을 줄 것이다 {{NN}}경우, NN문자의 16 진수 코드입니다. 간단히 조정할 수 있습니다.printf원하는 출력 스타일에 대해 .

여기에서 해당 프로그램이 작동하는 것을 볼 수 있습니다.

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

이 메서드는 모든 이진 문자를 동일한 '.'로 매핑합니다. 상징. 읽을 수있는 기호에 매핑하는 다른 방법이 있습니까?
Daniel YC Lin

물론, 내가 업데이트에서 제공 한 다른 필터 프로그램을 통해 실행할 수 있습니다.
paxdiablo 2012

1
tr '[:cntrl:] '.'더 낫다고 생각 합니다. 그리고 그것은 \000-\010\013\014\016-\037\177-\377'당신의 tr 구문에 있어야 합니다.
Daniel YC Lin

2
테스트 후 tr '[\000-\010\013\014\016-\037\177-\377]' '_'실행 가능한 cntrl은 내 경우에 적합하지 않습니다.
Daniel YC Lin

2
당신은 절약 할 수 cat배관에 의해 단계 grep --texttr대신 그 반대의. 또한 여러 파일을 grep하고 출력에서 ​​파일 이름 참조를 유지할 수 있습니다.
aaaantoine 2014-08-07

33

"문자열"을 사용하여 이진 파일에서 문자열을 추출 할 수 있습니다. 예를 들면

strings binary.file | grep foo

소스는 각 줄에 UID가있는 디버그 로그 였기 때문에 잘 작동했습니다. 감사.
mbrownnyc 2013-08-06

나에게도 잘 작동했습니다. 답변 해 주셔서 감사합니다. 내 하루 저장 :)
Shekhar 2014 년

2
@paxdiablo의 답변에 감사하지만 빠른 답변과 일을 계속하려면 이것을 잘못 할 수 없습니다.

paxdiablo 솔루션을 사용하려고 시도했지만 예상했던 결과를 얻지 못했습니다. @moodywoody 솔루션은 빠르고 간단하며 내가 필요한 것을 정확하게 출력합니다!
justinhartman 2014

20

grep이 다음을 사용하여 바이너리 파일을 보도록 강제 할 수 있습니다.

grep --binary-files=text

-o( --only-matching) 를 추가 하여 터미널을 지루하게 만들 수있는 바이너리 횡설수설을 얻지 않도록 할 수도 있습니다 .


출력이 터미널이고 터미널 드라이버가 일부를 명령으로 해석하면 심각한 부작용이 발생할 수있는 바이너리 가비지를 출력 할 수 있습니다.
Daniel YC Lin

을 사용 --only-matching하고 정규식이 임의의 이진 데이터와 일치하지 않으면 문제가 없습니다.
AB

정규식이 'first. * end'이고 바이너리 데이터에 '. *'패턴이 포함되어 있으면 포스트 프로세싱에 대한 프로세스를 수정할 수 없습니다. 어쨌든 감사합니다.
Daniel YC Lin 2012

16

Grep 2.21부터 바이너리 파일은 다르게 취급됩니다 .

바이너리 데이터를 검색 할 때 grep은 이제 텍스트가 아닌 바이트를 줄 종결 자로 취급 할 수 있습니다. 이렇게하면 성능이 크게 향상 될 수 있습니다.

이제 이진 데이터를 사용하면 텍스트가 아닌 모든 바이트 (줄 바꿈 포함)가 줄 종결 자로 처리됩니다. 이 동작을 변경하려면 다음을 수행 할 수 있습니다.

  • 를 사용하십시오 --text. 이렇게하면 줄 바꿈 만 줄 종결자가됩니다.

  • 를 사용하십시오 --null-data. 이렇게하면 null 바이트 만 줄 종결자가됩니다.


5

grep -a는 grep이 바이너리라고 생각하는 파일에서 grep을 검색하고 출력하도록합니다. grep -a re test.log


3

James Selvakumar가 이미 말했듯 grep -a이 트릭을 수행합니다. -a 또는 --text는 Grep이 입력 스트림을 텍스트로 처리하도록합니다. 맨 페이지 http://unixhelp.ed.ac.uk/CGI/man-cgi?grep 참조

시험

cat test.log | grep -a somestring

2

넌 할 수있어

strings test.log | grep -i

이것은 출력을 읽을 수있는 문자열로 grep으로 변환합니다.


0

Word Extractor 도구를 사용해 볼 수도 있습니다 . Word Extractor는 컴퓨터의 모든 파일과 함께 사용하여 인간 텍스트 / 단어를 포함하는 문자열을 바이너리 코드 (exe 응용 프로그램, DLL)에서 분리 할 수 ​​있습니다.


내 경우에는 단어 추출기가 필요하지 않으며 줄 번호를 유지해야합니다.
Daniel YC Lin

0

다음은 "문자열"명령이 설치되지 않은 시스템에서 사용한 것입니다.

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

원하지 않는 항목을 제거하기 위해 약간의 후 처리가 필요한 "cat -v filename"과 달리 이것은 텍스트를 인쇄하고 인쇄 할 수없는 문자를 한 번에 제거합니다. 이진 데이터 중 일부는 인쇄 가능할 수 있으므로 좋은 항목 간에는 여전히 횡설수설 할 수 있습니다. 나는 당신이 그것을 사용할 수 있다면 문자열 이이 의미없는 말도 제거한다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.