Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have some database dumps from a Windows system on my box. They are text files. I'm using cygwin to grep through them. These appear to be plain text files; I open them with text editors such as notepad and wordpad and they look legible. However, when I run grep on them, it will say binary file foo.txt matches.

I have noticed that the files contain some ascii NUL characters, which I believe are artifacts from the database dump.

So what makes grep consider these files to be binary? The NUL character? Is there a flag on the filesystem? What do I need to change to get grep to show me the line matches?

share|improve this question
    
--null-data may be useful if NUL is the delimiter. –  Steve-o Sep 1 '11 at 13:27

6 Answers 6

up vote 26 down vote accepted

If there is a NUL character anywhere in the file, grep will consider it as a binary file.

There might a workaround like this cat file | tr -d '\000' | yourgrep to eliminate all null first, and then to search through file.

share|improve this answer
12  
... or use -a/--text, at least with GNU grep. –  derobert Nov 26 '12 at 20:44
    
@derobert: actually, on some (older) systems, grep see lines, but its output will truncate each matching line at the first NUL (probably becauses it calls C's printf and gives it the matched line?). On such a system a grep cmd .sh_history will return as many empty lines as there are lines matching 'cmd', as each line of sh_history has a specific format with a NUL at the begining of each line. (but your comment "at least on GNU grep" probably comes true. I don't have one at hand right now to test, but I expect they handle this nicely) –  Olivier Dulac Nov 25 '13 at 11:46
    
+1 for using -a / --text with GNU grep, because you can mix this easily with recursive search, e.g. egrep -r -a mystring . Thanks @derobert –  phil_w Jul 14 at 19:08
    
Is the presence of a NUL character the only criteria? I doubt it. It's probably smarter than that. Anything falling outside the Ascii 32-126 range would be my guess, but we'd have to look at the source code to be sure. –  Michael Martinez Aug 14 at 16:58
    
My info was from the man page of the specific grep instance. Your comment about implementation is valid, source trumps docs. –  bbaja42 Aug 18 at 22:31

You can use the strings utility to extract the text content from any file and then pipe it through grep, like this: strings file | grep pattern.

share|improve this answer
    
Ideal for grepping log files that might be partly corrupted –  Hannes R. Feb 27 at 7:43

The file /etc/magic or /usr/share/misc/magic has a list of sequences that the command file uses for determining the file type.

Note that binary may just be a fallback solution. Sometimes files with strange encoding are considered binary too.

grep on Linux has some options to handle binary files like --binary-files or -U / --binary

share|improve this answer

One of my text files was suddenly being seen as binary by grep:

$ file foo.txt
foo.txt: ISO-8859 text

Solution was to convert it by using iconv:

iconv -t UTF-8 -f ISO-8859-1 foo.txt > foo_new.txt
share|improve this answer
1  
This happened to me as well. In particular, the cause was an ISO-8859-1-encoded non-breaking space, which I had to replace with a regular space in order to get grep to search in the file. –  Gallaecio Jun 9 at 13:50
1  
grep 2.21 treats ISO-8859 text files as if they are binary, add export LC_ALL=C before grep command. –  netawater Aug 17 at 2:52

Actually answering the question "What makes grep consider a file to be binary?", you can use iconv:

$ iconv < myfile.java
iconv: (stdin):267:70: cannot convert

In my case there were Spanish characters that showed up correctly in text editors but grep considered them as binary; iconv output pointed me to the line and column numbers of those characters

share|improve this answer

I had the same problem. I used vi -b [filename] to see the added characters. I found the control characters ^@ and ^M. Then in vi type :1,$s/^@//g to remove the ^@ characters. Repeat this command for ^M.

Warning: To get the "blue" control characters press Ctrl+v then Ctrl+M or Ctrl+@. Then save and exit vi.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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