输出locate txt | head
:
/etc/brltty/brl-ba-all.txt
/etc/brltty/brl-bd-all.txt
/etc/brltty/brl-bl-18.txt
/etc/brltty/brl-bl-40_m20_m40.txt
/etc/brltty/brl-ec-all.txt
/etc/brltty/brl-ec-spanish.txt
/etc/brltty/brl-eu-all.txt
/etc/brltty/brl-lb-all.txt
/etc/brltty/brl-lt-all.txt
/etc/brltty/brl-mb-all.txt
输出locate *.txt | head
:
/home/abc/capital.txt
/home/abc/state.txt
为什么输出结果会有如此巨大的差异?第二个命令似乎只检查我的主文件夹,但第一个命令似乎检查许多目录。为什么会这样?
答案1
locate txt
查找路径包含 1 的所有文件(任何类型,包括常规文件、符号链接、目录、套接字...)txt
,因此包括/foo/xtxty/bar
、/foo/bar.txt
、/foo/txt.bar
等。
locate *.txt
是错误的,因为它*
没有被引用,所以*.txt
shell 会首先将其扩展为当前目录中与该模式匹配的所有文件名,并将结果传递给locate
,因此,例如,如果当前目录包含a.txt
和b.txt
,那么最终将运行它根据实现来locate a.txt b.txt
定位包含 a.txt
和或 的路径,两者都例如(您的路径看起来像是第一类别中的路径,并且您可能从内部运行命令)。b.txt
locate
/foo/da.txtob.txt
/home/abc
如果当前目录中没有.txt
文件,则根据 shell 的不同,您会收到错误或locate
以*.txt
字面意思作为参数进行调用。
要始终locate
使用您想要的文字进行调用*.txt
,您需要确保*
为 shell 引用该文字,如果在类似 Bourne 的 shell 中"..."
,则使用'...'
或反斜杠,单引号是最好的,因为它们引用 Bourne 中的每个字符类似 shell,是 shell 中最便携的:
locate '*.txt'
然后,由于该参数包含通配符 ( *
),locate
因此从子字符串搜索切换到模式匹配搜索(与 shell 或find -name
其他识别的搜索相同)并返回与该模式匹配的所有文件路径,即所有.txt
以/foo/.txt
、 或结尾的文件路径/foo/bar.txt
。
locate
不是标准命令,并且有许多不兼容的实现,但上面的这些简单行为对于大多数(如果不是全部)来说是常见的。大多数实现支持各种选项来进行不同的匹配。检查您自己的locate
文档man locate
,而不是互联网上的一些随机页面,因为它们可能很好地记录了不同的实现和/或版本。
1 并且在定位数据库上次更新时确实存在
答案2
<command> *.txt
例如,当您使用像 () 这样的通配符时,扩展是由您的 shell 完成的,而不是您正在运行的命令,或者在本例中是locate
。
如果您想确保通配字符传递给您正在运行的命令,请将其放在引号中:
locate "*.txt"
或使用以下命令逃避它\
:
locate \*.txt
此外,locate
有一个或多或少基于正则表达式的匹配算法,但不完全是。如果搜索txt
,它会假设您希望txt
成为文件名的一部分,而不一定是在末尾。
你能强制正则表达式处理:
locate -r "txt$"
有关更多详细信息,请参阅locate
手册页
答案3
locate
需要图案作为参数。由于*.txt
没有被引用,shell 会尝试首先扩展它而不是逐字传递它。
另外,请注意:
作为一种特殊情况,不包含通配字符(“foo”)的模式会像“*foo*”一样进行匹配。
所以locate txt
相当于locate '*txt*'
.假设当前目录只包含a.txt
and b.txt
,则locate *.txt
扩展为locate a.txt b.txt
, and so 相当于locate '*a.txt*' '*b.txt*'
。