我有一个文件包含如下内容的行
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
在一个shell脚本中,我想要grep u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
怎么实现?
我尝试了grep "u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'"
文件,没有任何返回。
答案1
使用-F
选项(对于固定字符串搜索,以前使用该实用程序完成fgrep
):
grep -F "u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'" file
.
和字符\
是正则表达式运算符,一个匹配任何单个字符,另一个用于匹配逃脱正则表达式运算符或引入新的运算符(尽管在前面x
,POSIX 未指定该行为,并且可能因实现而异)。
因此,如果没有-F
,您就需要同时逃避两者。
由于在类似 Bourne 的 shell 中或fish
, inside"..."
也\
对 shell 具有特殊的转义含义,因此您还需要对其进行另一轮转义:
grep "u2py\.DynArray value=b'F\\\\xfeVOC\\\\xfeD_VOC'" file
在 csh 或 tcsh 中,这将是:
grep "u2py\.DynArray value=b'F\\xfeVOC\\xfeD_VOC'" file
shellrc
和派生类不支持"..."
作为引用运算符。您需要使用单引号:
grep 'u2py\.DynArray value=b''F\\xfeVOC\\xfeD_VOC''' file
(单引号表示为''
单引号内。参见如何像普通字符一样使用特殊字符?了解更多信息)。
答案2
要么使用:
$ cat <<\END | grep -Ff - file
u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
END
或者
$ var='u2py.DynArray value=b'"'"'F\xfeVOC\xfeD_VOC'"'"
$ grep -F -- "$var" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
事实证明问题出在\
(反斜杠)而不是'
(引号)。但首先,.
需要将 a 引用为正则表达式中的文字。
$ grep "u2py\.DynArray value=b'F" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
正如您在上面看到的,'
是通过 grep 找到的。
但要找到 \x,bash 中的变化是巨大的:
$ grep "u2py\.DynArray value=b'F\\\\x" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
为什么是四个\
?因为 shell 将 2 转换\\
为 ,\
并且 grep 接收 2\\
将其解释为 1,\
因为\
这也是正则表达式中的特殊字符。
我们可以看到这两个步骤:
$ 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
我们可以减少一使用 grep 选项的解释级别-F
。
$ 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
或者,没有set -x
:
$ grep -F "u2py.DynArray value=b'F\\x" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
最后一层的“解释”很难消除。
和全部Bourne shell 就可以做到这一点。和POSIX 需要它。
如果可以在标准输出上生成要搜索的确切字符串,我们可以使用
grep -Ff - file
-F
从文件 ( -f
) 标准输入 ( -
) 内搜索确切的“固定字符串”( ) file
。
这有可能似乎上班:
$ printf '%s\n' "u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'"
u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
但不,shell 仍在等待删除反斜杠:
printf '%s\n' "u2py.DynArray value=b'F\\\\xfeVOC\\\\xfeD_VOC'"
u2py.DynArray value=b'F\\xfeVOC\\xfeD_VOC'
避免删除反斜杠的唯一可靠方法是使用此处文档。
语法丑陋,但效果很好。
$ cat <<\END
u2py.DynArray value=b'F\xfeVOC\\\\xfeD_VOC'
END
请注意使用\END
(END
是引)。然后命令变成:
$ cat <<\END | grep -Ff - file
u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'
END
使用 var 就不需要此处文档一次var 具有正确的值:
$ var='u2py.DynArray value=b'"'"'F\xfeVOC\xfeD_VOC'"'"
$ grep -F -- "$var" file
xxx <u2py.DynArray value=b'F\xfeVOC\xfeD_VOC'>
或者也可以是grep -Fe "$var" file
。谢谢@StéphaneChazelas。