我是 Unix 新手,试图显示目录中的所有文件(不包括目录),因此我使用命令ls -p | grep -v /
.
它向我显示了一个看起来像这样的列表:
Process1
Process2
Process3
︙
但是当我使用该命令时ls -p | grep -v / | grep P*
,它只显示一些进程。为什么不显示所有进程?
编辑
我意识到我使用的是大写 P 而不是小写 p。这是个错误。
答案1
在你的第二个命令中,你grep P*
.这将提示 shell 进行文件名匹配P*
,即它将扩展P*
到以该字母开头的所有文件P
。
set -x
在 shell 中使用来查看执行的内容(使用 关闭跟踪set +x
)。实际上,我在自己的交互式 shell 会话中默认打开了跟踪,只是为了看看我在做什么。
仅双引号P*
无法解决此问题,因为正则表达式 P*
还匹配文件名,例如APPLE
和file.PP
,实际上hello_world.c
和所有其他文件名以及P*
还匹配文件名不 P
就在其中。
一般来说,你不应该解析的输出ls
不过,因此以下将是获取以字母 开头的文件(而不是目录)列表的更好方法P
:
$ find . -type f -maxdepth 1 -name "P*"
这将查找-type f
当前目录 ( .
) 中名称以P
( -name "P*"
) 开头的所有常规文件 ( )。该-maxdepth 1
选项仅限find
于该目录。否则它也会递归到子目录中。
做find
你正在做的事情grep -v /
,即去除列表中的目录而不是选择常规文件:
$ find . ! -type d -maxdepth 1 -name "P*"
这也会找到非常规文件,例如套接字等。在某些 shell 中,有必要转义或引用!
,即说
$ find . "!" -type d -maxdepth 1 -name "P*"
或者
$ find . \! -type d -maxdepth 1 -name "P*"
请注意,引用P*
很重要,这样您的 shell 就不会扩展它。
答案2
这"P*"
将匹配某些东西(或不是) 在 grep 看到参数之前从你的 shell 中。如果引用它,您将获得更好的结果,但请记住 grep 匹配正则表达式而不是通配符。
所以只要一个“P”就可以了。因为它是正则表达式,所以不需要星号*
来允许后面的字符"P"
要匹配(grep 默认情况下会忽略这些):
ls -p | grep -v / | grep "P"
或者
ls -p | grep -v / | grep '^P'
跟进更改后的问题,要忽略大小写,请使用-i
grep 选项,例如,
ls -p | grep -v / | grep -i '^P'
进一步阅读:
- grep - 在文件中搜索模式
-i
在搜索中执行模式匹配,不考虑大小写;参见XBD正则表达式一般要求。 - ls - 列出目录内容
-p
写一个 ('/'
) 在每个文件名之后(如果该文件是目录)。