76
votes

I have binary files that should be text (they're exported logs), but I can't open it with less (it looks ugly - it looks like a binary file). I found that I could open it with vi and I can cat it (you'll see the actual logs), but what I'd really like to do is grep through them (without having to open up each one with vi and then perform a search). Is there a way for me to do that?

locked by womble Sep 6 '18 at 1:25

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site so please do not use it as evidence that you can ask similar questions here. This question and its answers are frozen and cannot be changed. See the help center for guidance on writing a good question.

Read more about locked posts here.

85
votes

You can use grep anyway to search through the file - it does not really care if the input file is really text or not. From 'man grep':

    -a, --text
          Process a binary file as if it were text; this is equivalent to the --binary-files=text option.

   --binary-files=TYPE
          If  the  first few bytes of a file indicate that the file contains binary data, assume that the file is
          of type TYPE.  By default, TYPE is binary, and grep normally outputs either a one-line  message  saying
          that a binary file matches, or no message if there is no match.  If TYPE is without-match, grep assumes
          that a binary file does not match; this is equivalent  to  the  -I  option.   If  TYPE  is  text,  grep
          processes  a  binary  file  as  if  it  were  text; this is equivalent to the -a option.  Warning: grep
          --binary-files=text might output binary garbage, which can have nasty side effects if the output  is  a
          terminal and if the terminal driver interprets some of it as commands.

Please mark the words of caution at the end of the second paragraph. You might want to redirect the results from grep into a new file and examine this with vi / less.

  • grep does not really work. try grep on a storage device. it will run out of memory. it has a broken internal buffering mechanism that depends on reasonable length lines. – user239558 Dec 22 '17 at 19:13
41
votes

Pipe it through strings, which will strip out all of the binary code leaving just the text.

  • strings apparently does not understand utf-8 is text. – Javier Nov 9 '17 at 22:47
6
votes

Give bgrep a try. (original release / more recent fork)

  • I think this is the best answer here. It is so annoying to see bad implementations of binary search like here commandlinefu.com/commands/matching/grep-binary/… where the escaping by \x does not really work like here grep -P "\x05\x00\xc0" mybinaryfile. – Léo Léopold Hertz 준영 Jun 30 '15 at 10:05
  • I run bgrep "fafafafa" test_27.6.2015.bin |less but get test_27.6.2015.bin: 00005ee4. I would assume get fafafafa, since I was searching this. No manual in man. Any idea why such an output? – Léo Léopold Hertz 준영 Jun 30 '15 at 10:08
  • I opened a new thread about the functioning of bgrep here stackoverflow.com/q/31135561/54964 – Léo Léopold Hertz 준영 Jun 30 '15 at 10:18
  • what is the difference to grep -a? – rubo77 Jul 2 '16 at 2:35
  • Unfortunately, bash: bgrep: command not found... and No package bgrep available. – user145545 Apr 14 '17 at 6:12
5
votes

You can use these three commands:

  1. grep -a <sth> file.txt

  2. cat -v file.txt | grep <sth>

  3. cat file.txt | tr '[\000-\011\013-\037\177-\377]' '.' | grep <sth>

  • the tr does not seem to work on my solaris 10 box. Simple test: echo -e 'x\ty' | tr '[\000-\011\013-\037\177-\377]' '.' does not translate the tab. – user55570 Jun 27 '15 at 22:31
1
vote

Starting with Grep 2.21, binary files are treated differently:

When searching binary data, grep now may treat non-text bytes as line terminators. This can boost performance significantly.

So what happens now is that with binary data, all non-text bytes (including newlines) are treated as line terminators. If you want to change this behavior, you can:

  • use --text. This will ensure that only newlines are line terminators

  • use --null-data. This will ensure that only null bytes are line terminators

Not the answer you're looking for? Browse other questions tagged or ask your own question.