理解“grep”命令,显示的结果与预期不同

理解“grep”命令,显示的结果与预期不同

我是 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*还匹配文件名,例如APPLEfile.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'

跟进更改后的问题,要忽略大小写,请使用-igrep 选项,例如,

ls -p | grep -v / | grep -i '^P'

进一步阅读:

相关内容