Introduction
grep is a command widely used for text searching, but when used against binary files, it sometimes doesn't search as expected.
This article organizes the key points in a way that's easy for beginners to understand.
Reference: GNU grep
How to search binary files with grep
Create file
cat << 'EOF' > input.txt
Hello World
Linux Text Data
BINARY_DATA_START
EOF
Create file
echo -e ' \x00\x01\x02\x03\x04\xFF' >> input.txt
Create file
cat << 'EOF' >> input.txt
BINARY_DATA_END
grep sample text
EOF
Command to run
grep "grep" input.txt
Result
Binary file input.txt matches
Command to run
grep -a "BINARY_DATA" input.txt
Result
BINARY_DATA_START
BINARY_DATA_END
Command to run
grep --binary-files=text "BINARY_DATA" input.txt
Result
BINARY_DATA_START
BINARY_DATA_END
How it works
| Option | Mechanism | Use case |
|---|---|---|
| grep -a | Treats the binary file as text and searches it | Searching for strings inside binary files |
| grep --binary-files=text | Disables binary detection and processes the file as text | Same behavior as -a |
| Regular grep | Detects NUL bytes (0x00) etc. and judges the file to be binary | Searching text files |
Explanation
In the example above, echo -e '\x00\x01\x02\x03\x04\xFF' is used to append actual binary data to the file.
Using grep -a or --binary-files=text makes it possible to search for strings even in files containing binary data.
Why “Binary file matches” appears when searching binary files with grep
Create file
echo -e 'text\n\0binary\n' > binary.dat
Command to run
grep "binary" binary.dat
Result
Binary file binary.dat matches
Command to run
grep -a "binary" binary.dat
Result
binary
How it works
| Item | Description |
|---|---|
| Why "Binary file matches" is shown | Because grep detects a NUL character (\0) etc. and judges the file to be binary |
| grep's behavior | When judged binary, it skips displaying content and outputs "Binary file xxx matches" |
| Purpose | To prevent control characters or garbled text from being output to the terminal |
| -a option | Treats the binary file as text and displays matching lines |
| --binary-files=text | Behaves the same as -a |
Explanation
grep judges a file to be binary if it contains NUL characters etc.
Because of this, it normally doesn't display matching lines and only outputs the message "Binary file matches".
How to display only the file name in binary file search results with grep
Create file
cat << 'EOF' > input.txt
sample text
ERROR message
binary data
EOF
Create file
echo -e '\x00\x01\x02ERROR\x03\x04' > binary.dat
Command to run
grep -rlI "ERROR" .
Result
./input.txt
Command to run
grep -rl "ERROR" .
Result
./input.txt
./binary.dat
How it works
| Option | Role | Handling of binary files |
|---|---|---|
| -l | Displays only matching file names | Displays file names even for binary files |
| -r | Recursively searches a directory | Searches all files underneath |
| -I | Ignores binary files | Excludes binary files from the search |
Explanation
Using grep -l lets you display only the file names rather than the matching lines.
If you want to include binary files, use -l; if you want to exclude them, combine it with -I.
How to limit the file extensions targeted in binary file searches with grep
Create file
cat << 'EOF' > input.txt
error: database connection failed
EOF
Create file
echo -e '\x00\x01\x02error\x03\x04' > sample.bin
Create file
echo -e 'error: application failed\n' > sample.log
Create file
echo -e 'error: network failed\n' > sample.txt
Command to run
grep --include="*.log" --include="*.txt" -rn "error" .
Result
./sample.log:1:error: application failed
./sample.txt:1:error: network failed
Command to run
grep -rn "error" .
Result
./sample.log:1:error: application failed
./input.txt:1:error: database connection failed
./sample.txt:1:error: network failed
Binary file ./sample.bin matches
How it works
| Item | Description |
|---|---|
| grep -r | Recursively searches under a directory |
| --include="*.log" | Limits the search to .log files only |
| --include="*.txt" | Limits the search to .txt files only |
| Excluding binary files | Excludes anything outside the specified extensions, so .bin can be left out |
| Effect | Avoids unwanted "Binary file matches" results |
Explanation
grep includes binary files when performing a recursive search, causing unintended matches.
Using --include to limit the target extensions lets you efficiently search only text files.
How to use grep's --binary-files option
Create file
echo -e 'Hello World\nBinaryData\n\0\nAnother Line\n' > binary.txt
Command to run
grep "BinaryData" binary.txt
Result
Binary file binary.txt matches
Command to run
grep --binary-files=text "BinaryData" binary.txt
Result
BinaryData
Command to run
grep --binary-files=without-match "BinaryData" binary.txt
Result
no output
How it works
| Item | Description |
|---|---|
| --binary-files=text | Treats binary files as text and shows search results normally. |
| --binary-files=without-match | Excludes binary files from the search and doesn't output anything even if they match. |
| Default behavior | When a binary file is detected, displays "binary file matches" without outputting its content. |
Explanation
grep judges files containing NULL characters etc. to be binary.
The --binary-files option lets you control whether binary files are searched as text or excluded from the search.
The difference between grep’s -a option and binary file search
Create file
cat << 'EOF' > input.txt
Hello World
Linux
grep sample
ABC
grep binary test
EOF
Create file
echo -e "\0\n" >> input.txt
Command to run
grep "grep" input.txt
Result
Binary file input.txt matches
Command to run
grep -a "grep" input.txt
Result
grep sample
grep binary test
How it works
| Item | grep | grep -a |
|---|---|---|
| Binary file detection | Treats the file as binary if a NUL character is detected | Forcibly treats the file as text |
| Search result | Displays only "binary file matches" | Displays matching lines |
| Use case | To avoid mis-displaying binary data | When you want to investigate strings mixed into binary data |
Explanation
Regular grep judges a file containing NUL characters to be binary and only reports a match.
Adding the -a option treats it as text, so strings contained inside the binary file can also be displayed.
How to treat binary files as text with grep
Create file
echo -e '\x00\x01\x02grep-test\x03\x04' > binary.dat
Command to run
grep 'grep-test' binary.dat
Result
Binary file binary.dat matches
Command to run
grep -a 'grep-test' binary.dat
Result
grep-test
Command to run
grep --binary-files=text 'grep-test' binary.dat
Result
grep-test
How it works
| Item | Description |
|---|---|
| Regular grep | When a binary file is detected, doesn't display the content and outputs "Binary file ~ matches" instead |
| -a | Treats the binary file as text (equivalent to --text) |
| --binary-files=text | Ignores the binary judgment and searches as text |
| Use case | When binary data is mixed into logs, or when investigating an executable with embedded strings |
Explanation
grep judges a file to be binary when it detects a NULL character etc.
Specifying -a or --binary-files=text lets you display search results as text even for binary files.
How to exclude binary files when searching with grep
Create file
cat << 'EOF' > input.txt
text data
error message
binary file
EOF
Create file
echo -e '\x00\x01\x02binary-data\x03\x04' > binary.dat
Command to run
grep --binary-files=without-match "binary" *
Result
input.txt:binary file
How it works
| Item | Description |
|---|---|
| grep | A command that searches for strings inside files |
| --binary-files=without-match | Excludes binary files from the search |
| "binary" | The keyword being searched for |
| * | Targets all files in the current directory |
| Effect | Removes noise from binary files, allowing only text files to be searched |
Explanation
Normally grep displays "Binary file matches" when it detects a binary file.
Specifying --binary-files=without-match ignores binary files during the search, which is convenient for source code or log searches.
The difference between grep’s -I option and excluding binary files
Create file
echo -e 'text data\nbinary\0data\nhello world\n' > input.txt
Command to run
grep "data" input.txt
Result
Binary file input.txt matches
Command to run
grep -I "data" input.txt
Result
no output
Command to run
grep --binary-files=without-match "data" input.txt
Result
no output
How it works
| Item | grep -I | grep --binary-files=without-match |
|---|---|---|
| Behavior | Treats files judged binary as non-matching | Treats binary files as non-matching |
| Relationship | -I is shorthand for --binary-files=without-match | Same behavior specified by its full option name |
| Readability | Shorter to type | Meaning is explicit, suitable for scripts |
| Use case | Manually typed commands | Config files, shell scripts, etc. |
Explanation
-I is an abbreviation of --binary-files=without-match, and there's no difference in behavior. Both effectively exclude binary files from the search and prevent the "Binary file matches" display.
How to control binary files during a recursive search with grep
Create file
cat << 'EOF' > sample.txt
Hello World
ERROR
EOF
Create file
cat << 'EOF' > app.log
ERROR
Application ERROR
EOF
Create file
cat << 'EOF' > readme.md
grep sample
ERROR
EOF
Create file
mkdir -p bin images
Create file
echo -e '\x7fELF\x02\x01\x01ERROR\0' > bin/app
Create file
echo -e '\x89PNG\r\n\x1a\nERROR\0' > images/logo.png
Command to run
grep -r "ERROR" .
Result
Binary file ./bin/app matches
Binary file ./images/logo.png matches
./readme.md:ERROR
./app.log:ERROR
./app.log:Application ERROR
./sample.txt:ERROR
Command to run
grep -rI "ERROR" .
Result
./readme.md:ERROR
./app.log:ERROR
./app.log:Application ERROR
./sample.txt:ERROR
Command to run
grep -ra "ERROR" .
Result
./bin/app:ELFERROR
./images/logo.png:ERROR
./readme.md:ERROR
./app.log:ERROR
./app.log:Application ERROR
./sample.txt:ERROR
How it works
| Option | Mechanism | Use case |
|---|---|---|
| -r | Recursively searches the directory tree; when it detects a binary file, it doesn't display the content and outputs "Binary file ~ matches" instead | Standard recursive search |
| -rI | Excludes binary files from the search | When you only want to search source code or text files |
| -ra (--binary-files=text) | Treats binary files as text and displays the matching content as well | When you want to search strings inside binary files too |
Explanation
Normally, grep doesn't display content when it detects a binary file and outputs "Binary file ~ matches" instead.
Specifying -I ignores binary files, and specifying -a treats binary files as text so their content can be displayed too.
Character encoding issues when searching binary files with grep
Command to run
grep "he" /bin/ls
Result
Binary file /bin/ls matches
Command to run
grep -a "he" /bin/ls
Result
Lines from the binary data containing the matched portion are displayed
Command to run
grep --binary-files=text "he" /bin/ls
Result
Lines from the binary data containing the matched portion are displayed
How it works
| Item | Description |
|---|---|
| grep's normal behavior | Judges a file to be binary if it detects NULL characters etc. |
| Binary file matches | A state where a match was found but content display is suppressed |
| -a | Treats the binary file as text |
| --binary-files=text | Behaves the same as -a |
| -I | Ignores binary files when searching |
| Relationship to encoding issues | Encoding misdetection or embedded NULL characters can cause even text files to be treated as binary |
Explanation
Internally, grep judges a file to be binary rather than text when it detects NULL characters etc.
Because of this, search results aren't displayed and instead show "binary file matches"; -a or --binary-files=text can be used to force it to be treated as text.
Cases where non-UTF-8 files get judged as binary by grep
Create file
cat << 'EOF' > input.txt
grep processes files as text by default.
When a file contains non-UTF-8 encoded data or NUL bytes (0x00),
grep may determine that the file is a binary file.
EOF
Create file
echo -e "\0" >> input.txt
Command to run
grep "grep" input.txt
Result
Binary file input.txt matches
Command to run
grep -a "grep" input.txt
Result
grep processes files as text by default.
grep may determine that the file is a binary file.
How it works
| Item | Description |
|---|---|
| grep's judgment | grep may judge a file to be binary when it detects a NUL byte |
| Relationship to non-UTF-8 | Encodings such as Shift_JIS or EUC-JP can also be judged binary depending on their content |
| Displayed message | Binary file input.txt matches |
| -a option | Ignores the binary judgment and processes the file as text |
Explanation
grep doesn't judge binary status from the encoding itself, but mainly from content such as NUL bytes.
Non-UTF-8 files can be mistakenly judged as binary depending on the byte patterns present, so use grep -a when needed.
How to combine grep and strings to search binary files
Create file
cat << 'EOF' > input.txt
Hello World
User: alice
Password: secret123
API_KEY=ABC123XYZ
ERROR: Connection failed
TOKEN=xyz987
EOF
Create file
echo -e '\x00\x01\x02' >> input.txt
Command to run
grep "ERROR" input.txt
Result
Binary file input.txt matches
Command to run
strings input.txt
Result
Hello World
User: alice
Password: secret123
API_KEY=ABC123XYZ
ERROR: Connection failed
TOKEN=xyz987
Command to run
strings input.txt | grep "ERROR"
Result
ERROR: Connection failed
Command to run
strings input.txt | grep -Ei "password|token"
Result
Password: secret123
TOKEN=xyz987
How it works
| Item | Description |
|---|---|
| strings | Extracts only the printable strings from a binary file |
| grep | Searches the extracted strings for the specified keyword |
| Pipe (|) | Passes the output of strings to grep to narrow down the search |
| Benefit | Lets you efficiently find embedded strings rather than searching the whole binary file directly |
Explanation
By extracting readable strings with strings and then searching with grep, you can quickly find error messages or credentials embedded in executables or compressed files.
This is a commonly used basic combination when investigating binary files.
Analyzing binary files using grep and hexdump together
Create file
cat << 'EOF' > sample.bin
Hello
Linux
grep
Binary
DATA
EOF
Create file
printf '\0TEXT' >> sample.bin
Command to run
grep 'TEXT' sample.bin
Result
Binary file sample.bin matches
Command to run
grep -a 'TEXT' sample.bin
Result
TEXT
Command to run
hexdump -C sample.bin
Result
00000000 48 65 6c 6c 6f 0a 4c 69 6e 75 78 0a 67 72 65 70 |Hello.Linux.grep|
00000010 0a 42 69 6e 61 72 79 0a 44 41 54 41 0a 00 54 45 |.Binary.DATA..TE|
00000020 58 54 |XT|
00000022
How it works
| Command | Mechanism |
|---|---|
| grep 'TEXT' sample.bin | Contains a NUL (0x00), so it's judged binary and outputs Binary file sample.bin matches. |
| grep -a 'TEXT' sample.bin | The -a option treats it as text and displays the matching line. |
| hexdump -C sample.bin | Displays the file in hexadecimal and ASCII format, letting you check the binary data's contents. |
Explanation
grep judges a file containing NUL characters to be binary.
Using hexdump -C alongside it lets you check the actual byte sequence in addition to the strings, which helps when analyzing binary files.
How to resolve cases where binary file searches fail with grep
Create file
cat << 'EOF' > input.txt
Text data
ERROR: application failed
Process completed successfully
EOF
Create file
echo -e '\x89PNG\r\n\x1a\nERROR: binary data\n\0' > binary.dat
Command to run
grep "ERROR" *
Result
Binary file binary.dat matches
input.txt:ERROR: application failed
Command to run
grep -a "ERROR" *
Result
binary.dat:ERROR: binary data
input.txt:ERROR: application failed
Command to run
grep --binary-files=text "ERROR" *
Result
binary.dat:ERROR: binary data
input.txt:ERROR: application failed
How it works
| Option | Mechanism | Use case |
|---|---|---|
| grep "ERROR" * | Files grep judges to be binary have their content suppressed and "binary file matches" is shown instead | Standard search |
| grep -a "ERROR" * | Treats binary files as text when searching | Checking strings inside binary files |
| grep --binary-files=text "ERROR" * | Disables binary judgment and searches as text | For scripts and automated processing |
Explanation
grep may detect NUL characters etc. and judge a file to be binary, in which case it won't display the matched content.
Using -a or --binary-files=text lets you search strings inside binary files the same way as ordinary text.
Key points for understanding and searching binary files with grep
grep normally suppresses output when it detects a binary file, displaying Binary file matches instead.
If you want to check the content, use -a or --binary-files=text; if you want to exclude it, -I or --binary-files=without-match is useful.
If search results don't come out as expected, checking the options, character encoding, and the type of target file is the quickest path to a solution.

