我想查找所有提供文件名中包含“ssl”的共享对象的软件包。apt-file 手册页说:
--regexp | -x 将模式视为 (perl) 正则表达式。有关详细信息,请参阅 perlreref(1)。如果没有此选项,模式将被视为要搜索的文字字符串。
因此我的第一次尝试是
apt-file search --regexp .*ssl.*\.so.*
然而,这给了我如下结果
诙谐的例子:/usr/lib/Wt/examples/feature/client-ssl-auth/resources
文件名中没有“.so”。
我玩了一下,然后想出了
apt-file search --regexp .*ssl.*\\.so.*
即我转义了原本应该转义点的反斜杠。这给了我想要的结果。
有人可以解释一下为什么在这种情况下需要双反斜杠吗?
答案1
您需要双反斜杠,\\
因为单反斜杠不仅是正则表达式转义字符,也是您的 shell 使用的字符。例如,您对点进行转义,在 shell 级别上,它只是解释为常规点,然后传递给 apt-get 并处理每个字符(常规点通常会这样做)。
因此答案是,首先字符串由 shell 解释,其中反斜杠有一个含义,并且后然后,它被传递给 apt-get。apt-get 的正则表达式引擎会再次解释预处理的字符串。反斜杠已被替换(并且含义也略有不同)。
另一个解决方案是将正则表达式放在引号中,如下所示:
apt-file search --regexp '.*ssl.*\.so.*'
答案2
问题是由于您没有使用引用,所以您需要转义 shell 和正则表达式解释器,以将其解释.
为文字。
这就是引用如此重要的原因。如果你在第一个模式两边加上引号,它就会起作用:
apt-file search --regexp '.*ssl.*\.so.*'
要注意的主要一点是,我们的最终目标是让正则表达式解释器apt-file
按.
字面意思而不是通常的方式,即任何单个字符。
第二种情况:
apt-file search --regexp .*ssl.*\\.so.*
这里的第一个
\
是转义 shell,因为 shell 将任何内容视为\
反斜杠转义序列的一部分,例如 shell 将其视为\n
换行符、\t
水平制表符等。对于单个字符,
\
如.*ssl.*\.so.*
,shell 将其.
视为\
转义的特殊字符,但.
对 shell 没有特殊含义,因此\
shell 只会将其删除,只留下.
。使用\\.
shell 会删除第一个字符,\
留下一个\.
文字,在 shell\
中用 表示。\\
因此,我们将Regex 模式留给Perl Regex 解释器
.*ssl.*\.so.*
进行解释。这样您就可以得到所需的结果。apt-file
答案3
如果不使用引用模式,则必须对 RegEx 的反斜杠进行转义:
apt-file search --regexp .*ssl.*\\.so.*
使用引用模式,您不需要这样做:
apt-file search --regexp '.*ssl.*\.so.*'
例子
$ apt-file search --regexp .*ssl.*\\.so.* > ~/tmp/bar
$ apt-file search --regexp '.*ssl.*\.so.*' > ~/tmp/foo
$ diff foo bar | wc -l
0