Either use:
$ cat <<\END | grep -Ff - file
u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
END
Or
$ var='u2py.DynArray value=b'"'"'F\xfeVOC\xfeD_VOC'"'"
$ grep -F -- "$var" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
It turns out the problem is with the \
(backslash) not the '
(quotes).
But first, a .
needs to be quoted to be literal in a regex.
$ grep "u2py\.DynArray value=b'F" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
As you can see above, the '
is found by grep.
But to find a \x, the change is drastic in bash:
$ grep "u2py\.DynArray value=b'F\\\\x" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
Why four \
? Because the shell converts two \\
to \
and grep receiving two \\
interprets it as one \
as \
is also an special character in regexes.
We can see the two steps with:
$ set -x; grep "u2py\.DynArray value=b'F\\\\x" file ; set +x
+ grep --color=auto 'u2py\.DynArray value=b'\''F\\x' file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
+ set +x
We can reduce one level of interpretation with the -F
option of grep.
$ set -x; grep -F "u2py.DynArray value=b'F\\x" file ; set +x
+ grep --color=auto -F 'u2py.DynArray value=b'\''F\x' file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
+ set +x
Or, without set -x
:
$ grep -F "u2py.DynArray value=b'F\\x" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
That last level of "interpretation" is difficult to remove.
And all Bourne shells do that. And POSIX require it.
If it is possible to generate on stdout the exact string to search, we can use
grep -Ff - file
To search for the exact "Fixed string" (-F
) from the file (-f
) standard input (-
) inside file
.
This might seem to work:
$ printf '%s\n' "u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'"
u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
But no, the shell is still waiting to remove backslashes:
printf '%s\n' "u2py.DynArray value=b'F\\\\xfeVOC\\\\xfeD_VOC'"
u2py.DynArray value=b'F\\xfeVOC\\xfeD_VOC'
The only robust way to avoid the backslash removal is to use a here document.
Ugly syntax, but works pretty well.
$ cat <<\END
u2py.DynArray value=b'F\xfeVOC\\\\xfeD_VOC'
END
Please note the use of \END
(the END
is quoted).
And the command then becomes:
$ cat <<\END | grep -Ff - file
u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
END
With a var there is no need for a here document once the var has the correct value:
$ var='u2py.DynArray value=b'"'"'F\xfeVOC\xfeD_VOC'"'"
$ grep -F -- "$var" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
Alternatively could be grep -Fe "$var" file
. Thanks @StéphaneChazelas.
grep "F\xfe"
could not work but bothgrep "F\\xfe"
andgrep "F\\\\xfe"
would work. What shell are you using? – Stéphane Chazelas May 14 '20 at 06:49grep -F "u2py.DynArray value=b'F\\xfeVOC\\xfeD_VOC'" file
. It also works, meaning that the shell is removing one of the two backslash. It would be more visible trying to match two backslash. – May 15 '20 at 04:31