首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对grep和*通配符感到困惑

对grep和*通配符感到困惑
EN

Ask Ubuntu用户
提问于 2019-08-21 10:15:40
回答 2查看 3.7K关注 0票数 5

为了查找与“flash_drive_data”无关的所有文件/目录,我正在运行以下命令:

代码语言:javascript
复制
find . -not -path './flash_drive_data*' | grep "./*flash*"

我尝试过的一些事情让我感到困惑:

  1. 当我运行上面的命令时,我会得到一些“部分”点击(即它们不完全匹配*flash*模式)。例如:
代码语言:javascript
复制
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/cli.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/signals.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/templating.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/sessions.pyi
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json
./.local/lib/python3.7/site-packages/jedi/third_party/typeshed/third_party/2and3/flask/json/tag.pyi

结尾处的3/flas正在突出显示。

  1. 当我将grep "*flash*"替换为grep "*"时,我希望获得find返回的所有文件,但没有。为什么?然后,当我做grep "**"时,我相信我得到了所有的文件(或者至少我认为我得到了)。再说一遍,这是为什么?
  2. 最后,我在上面所做的工作的目的是确保当我运行find . -not -path './flash_drive_data*'时,我没有得到任何与flash_drive_data相关的信息。看起来我做到了(就像我前面解释的那样,对于grep有一些意想不到的行为)。但是,当我运行时:find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' +

我得到了输出,包括:

代码语言:javascript
复制
./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/

因此,flash_drive_data文件被包括在内。

EN

回答 2

Ask Ubuntu用户

回答已采纳

发布于 2019-08-22 06:10:48

代码语言:javascript
复制
find . -not -path './flash_drive_data*' | grep "./*flash*"

这里的问题是,grep使用正则表达式,而find -path使用shell glob样式模式匹配。星号在这两个词中有不同的含义。

正则表达式./*flash*首先匹配任意字符(.),然后匹配零或多个斜杠(/*),然后匹配文字字符串flas,然后匹配h字符的任何数字(零或多个)。3/flas与此匹配(与零倍h匹配),例如reflash (与零倍/匹配)。

您可以使用grep flash代替,因为它与输入中的任何位置匹配,所以引导和跟踪“匹配任何”部件都是不必要的。

或者使用find -path './*flash*' -and -not -path './flash_drive_data*'

当我用grep "*flash*"代替grep "*"时,我得到了没有火柴。

因为星号的意思是“前一个原子的任何数目”,所以这里没有很好的定义。grep将其解释为文字星号,但实际上应该是一个错误。

但是,当我运行:find . -not -path './flash_drive_data*' -exec tar cfv home.tar.bz '{}' +时,我得到了输出,包括:./flash_drive_data/index2/ask-sdk-core/dist/dispatcher/error/handler/,所以flash_drive_data文件被包括在内。

注意,tar递归地存储文件,该find的第一个输出是当前目录的.,因此所有内容都将被存储。您可能希望将! -type dfind一起用于从输出中排除目录,或者(更好的)查看-exclude=PATTERN选项到tar

票数 3
EN

Ask Ubuntu用户

发布于 2019-08-21 10:57:35

您混淆了*对于外壳文件名扩展Posix基本判据的不同含义。

在Regex中,*是前面字符的量词,所以h*意味着0或更多的h出现。如果您想要“任意数量的任何字符”,请使用.*

grep '*'将查找文字*,因为它前面没有任何可以量化的东西,而grep '**'希望0或更多的*出现,所以一切都符合0,因为任何事情的出现都是合适的。

无论如何,您应该使用带参数的find和参数-path "*/flash/*",而不是使用grep作为find的输出。

票数 15
EN
页面原文内容由Ask Ubuntu提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://askubuntu.com/questions/1167297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档