Answers:
完成现有答案:
ls
缺省目录列表实用程序ls
可以与shell的通配符结合使用。要搜索所有带有pattern的文件abc
:
ls abc* # list all files starting with abc---
ls *abc* # list all files containing --abc--
ls *abc # list all files ending with --abc
请注意,文件扩展名也与搜索结果相关。
tree
如果我们需要在目录树中列出文件,我们还可以发出命令tree
来搜索给定的模式,例如:
tree -P 'abc*' # list directory tree of file starting with abc---
tree -l 'def*' # exclude files starting with def---
在这种情况下,tree
它本身支持通配符。
ls
列出目录时,它会打开它,所以与做相同ls -l BirthdayPhotos
。您可以使用抑制这种行为ls -d B*
。
B*
视为目录规范?
B*
会扩展为匹配以开头的所有目录,B
所以您实际上是在传递ls
目录列表,因此它将为您打开所有目录。
ls -d ABC*
是作者问的问题。另外,代码段中的注释是错误的,ls abc*
列出了以abc开头的目录的内容。
有很多方法可以执行此操作,具体取决于您要对它们执行什么操作。通常,如果只想列出它们,则可以在终端中使用以下方法进行:
find | grep '^\./ABC'
...并替换ABC
为您的文字。
为了理解该命令,让我们对其进行分解:
find
列出当前目录及其子目录下的所有文件;单独使用它只会列出所有内容。请注意,find
输出以开头的每个文件或目录./
,指示它们的路径相对于当前目录。注意这一点很重要,因为这意味着我们将搜索以./ABC
而不是开头的结果ABC
。
竖线字符|
将一个命令的输出重定向到另一个命令,在这种情况下,的输出find
重定向到grep
。这称为管道。
grep
获取输出并使用给定的模式对其进行过滤^\./ABC
。
' '
来,以防止外壳解释其中的特殊字符。现在,模式本身是用一种称为正则表达式(简称regex)的特定语法编写的。正则表达式是,如果你掌握了它一个非常强大的搜索工具,有网站如这其中教你关于它的更深入,但请注意,grep
不是一个完整的正则表达式引擎,你不能用它做的一切。
为了我们的目的:
^
在正则表达式中匹配字符串的开头;如果它不在文件名的开头,则可以防止它与模式匹配。
.
在regex中也有特殊含义:意思是“在这里匹配任何单个字符”。如果要将其用作文字点,则必须\
在其之前使用反斜杠“转义” 它。(是的,在我们的案例中匹配任何角色都是无害的,但出于完整性考虑,我还是这样做了。)
find | grep
当您find
拥有完美的模式匹配功能时呢?
对我来说最简单的解决方案
ls | grep PATTERN
在这里,您可以在PATTERN中给出任何正则表达式。
例如,要查找名称中任意位置带有“ ab”的文件,请键入
ls | grep ".*ab.*"
要查找以“ ab”开头的文件,请键入
ls | grep "^ab"
如果您不知道ABC*
文件所在的目录,并且拥有数百万个文件,则此locate
命令是最快的方法。
$ locate /ABC
/mnt/clone/home/rick/.cache/mozilla/firefox/9fu0cuql.default/cache2/entries/ABC6AD2FEC16465049B48D39FD2FE538258F2A34
/mnt/clone/home/rick/.cache/mozilla/firefox/9fu0cuql.default/cache2/entries/ABCBFDA54262F47253F95ED6ED4131A465EE0E39
/mnt/clone/usr/src/linux-headers-5.0.1-050001/tools/lib/lockdep/tests/ABCABC.sh
/mnt/clone/usr/src/linux-headers-5.0.1-050001/tools/lib/lockdep/tests/ABCDBCDA.sh
/mnt/clone/usr/src/linux-headers-5.0.1-050001/tools/lib/lockdep/tests/ABCDBDDA.sh
/mnt/old/home/rick/.cache/mozilla/firefox/3vkvi6ov.default/cache2/entries/ABC0C99FCEABAD0C6AA2078CD025A1CDE48D7BA1
/usr/src/linux-headers-5.0.1-050001/tools/lib/lockdep/tests/ABCABC.sh
/usr/src/linux-headers-5.0.1-050001/tools/lib/lockdep/tests/ABCDBCDA.sh
/usr/src/linux-headers-5.0.1-050001/tools/lib/lockdep/tests/ABCDBDDA.sh
笔记:
find
从/
根目录开始的命令将花费很长时间,并且会产生许多权限错误。sudo updatedb
。蟒蛇:
$ python -c 'import sys,os;found=[os.path.join(r,i) for r,s,f in os.walk(".") for i in f if i.startswith("ABC")];map(lambda x: sys.stdout.write(x+"\n") ,found)'
Perl:
$ perl -le 'use File::Find;find(sub{ -f && $_ =~/^ABC/ && print $File::Find::name },".")'
printf "%s" /path/to/files/ABC*
这是在两端锚定的全局模式匹配。这将匹配所有以“ ABC”开头的文件,例如“ ABC”,“ ABC.txt”,“ ABC123”,而不是“ xABC”。从命令行使用“ ls”代替“ printf”是一种安全的选择,但是,根据您同意谁的观点,在脚本中使用“ ls”并不安全。在这种情况下,将“ printf”与全局模式匹配一起使用是安全的。如果要在脚本中使用此命令,则“ printf”的输出在输出流的末尾将不包含换行符,如下所示:
printf "%s" /path/to/files/ABC*
返回值:
/path/to/files/ABC /path/to/files/ABC123
如果需要在每个实例后换行:
printf "%s\n" /path/to/files/ABC*
返回值:
/path/to/files/ABC
/path/to/files/ABC123
如果您在运行“ printf”命令时以这种方式输入“ / path / to / files /”,则会保留在输出中。没有它,只会显示文件名:
printf "%s" ABC*
退货
ABC ABC123
假设您在文件所在的目录中运行命令。
echo /path/to/files/ABC* | tr " " "\n"
不是一个好主意。考虑是否有一个文件/path/to/files/ABC EFG
,文件名中有一个空格。您tr
将文件名分成两行,这是不好的。如果文件名中包含多个空格,则更糟。我建议您printf "%s\n" ABC*
改用它,这应该有助于文件名中的空格,但对于其他特殊字符(例如\n
假设我在根目录下,而我只想要etc目录的列表:我们这样写,
find -type d -name "etc"
结果我们得到了
[root@unix /]# find -type d -name "etc"
./etc
./usr/lib/firefox/bundled/etc
./usr/lib/unix-yarn/etc
./usr/lib/unix/etc
./usr/lib/festival/etc
./usr/bin/lib/vmware-tools/lib64/libconf/etc
./usr/bin/lib/vmware-tools/lib32/libconf/etc
./usr/etc
./usr/share/doc/oddjob-0.30/sample/etc
./usr/share/festival/lib/etc
./usr/local/etc
./usr/java/jdk1.7.0_25/lib/visualvm/etc
./home/user1/Desktop/VMware Tools/vmware-tools-distrib/lib/lib64/libconf/etc
./home/user1/Desktop/VMware Tools/vmware-tools-distrib/lib/lib32/libconf/etc
./home/user1/Desktop/VMware Tools/vmware-tools-distrib/etc
./home/user1/Desktop/VMware Tools/vmware-tools-distrib/caf/etc
另一个例子,
我们也可以这样写:
ls | grep "etc"
我们得到
etc
ls -l B*
,它会显示所有以“ 。”开头的目录的内容,B
而不仅仅是匹配目录的名称?