我正在运行以下命令来查找与“flash_drive_data”无关的所有文件/目录:
find . -not -path './flash_drive_data*' | grep "./*flash*"
我尝试过的一些事情让我感到困惑:
1. 当我运行上述命令时,我得到了一些“部分”匹配(即它们不完全匹配模式*flash*
。例如:
./.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
最后的 被突出显示。
2. 当我grep "*flash*"
仅用替换时grep "*"
,我期望获得 find 返回的所有文件,但我没有得到任何文件。为什么?然后,当我得到文件时,grep "**"
我相信我得到了所有文件(或者至少我认为我得到了所有文件)。同样,这是为什么呢?
3. 最后,我上面所做的目的是确保运行时find . -not -path './flash_drive_data*'
不会得到与 flash_drive_data 相关的任何内容。我似乎得到了(使用 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 文件。
答案1
*
你混淆了for的不同含义Shell 文件名扩展和Posix 基本正则表达式。
在正则表达式中,*
是其前面字符的量词,因此h*
表示 出现 0 次或多次h
。如果您想要“任意数量的任意字符”,请使用.*
。
grep '*'
会寻找文字,*
因为它前面没有任何可以量化的东西,而grep '**'
会寻找 0 次或更多次出现*
,因此一切都会适合,因为 0 次出现总是合适的。
无论如何,您应该使用find
带有参数-path "*/flash/*"
而不是grep
的输出find
。
答案2
find . -not -path './flash_drive_data*' | grep "./*flash*"
这里的问题是,grep
使用正则表达式,而find -path
使用 shell glob 样式的模式匹配。 星号在这两个中具有不同的含义。
正则表达式./*flash*
首先匹配任意字符(.
),然后匹配零个或多个斜杠(/*
),然后匹配文字字符串flas
,然后匹配任意数量(零个或多个)的h
字符。3/flas
例如 匹配 (零次h
),因此 eg 也匹配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 d
withfind
从输出中排除目录,或者(更好的方法是)查看-exclude=PATTERN
的选项tar
。