Bash tool grep shim (ugrep) misses matches for -E '(^|[^0-9])N' that GNU grep finds

Status Open
Reported on v2.1.285
Maintainer reply None cached
Activity 0 comments · opened Sep 30, 2026

Claude Code 2.1.285 (Linux, bash). In the Bash tool, grep is the built-in grep→ugrep shell function. It returns no match for an -E pattern that alternates ^ with a negated bracket class; /usr/bin/grep and rg both match.

Minimal reproduction, run inside the Bash tool:

s='5798-72bbf60eb5b8.json'
printf '%s\n' "$s" | grep -qE '(^|[^0-9])5798'; echo shim=$?            # 1 (no match)
printf '%s\n' "$s" | /usr/bin/grep -qE '(^|[^0-9])5798'; echo gnu=$?    # 0 (match)

Narrowing, same input:

| pattern | shim | GNU grep |
|---|---|---|
| (^\|[^0-9])5798([^0-9]\|$) | 1 | 0 |
| (^\|[^0-9])5798 | 1 | 0 |
| (^\|x)5798 | 0 | 0 |
| ^5798 | 0 | 0 |
| 5798([^0-9]\|$) | 0 | 0 |

So (^|x) works but (^|[^0-9]) at the start of the line does not.

Impact: a silent false negative. An agent counted records with grep -qE "(^|[^0-9])$n([^0-9]|$)", got 0 of 99 instead of 5, and reported "none" to the user. Nothing signals that the shim, not GNU grep, answered.

Related, different defects: #88802 (inverted exit code with -v -q) and #69736 (opt-out request).

View original on GitHub ↗