在 find 命令的正则表达式中使用修饰符?

在 find 命令的正则表达式中使用修饰符?

我正在尝试使用 find 命令的正则表达式来使用点字符匹配换行符。这通常是通过s修饰符来完成的;然而,不同的正则表达式引擎有不同的格式,我无法确切地弄清楚如何编写正则表达式,以便 find 命令将匹配换行符。例如,我将如何更改以下简单命令以匹配所有文件,包括名称中包含换行符的文件:

find /home/user -regex ".*"

我已经尝试过"(?s).*",,"/.*/s"可能还有其他一些。

答案1

我的 GNU find 版本支持几种不同的正则表达式变体,可以使用以下命令进行选择-regextype

有效类型为“findutils-default”、“awk”、“egrep”、“ed”、“emacs”、“gnu-awk”、“grep”、“posix-awk”、“posix-basic”、“posix-” egrep'、'posix-extend'、'posix-minimal-basic'、'sed'。

几乎所有这些都让点匹配换行符,...除了emacs,这是默认值。

所以,使用其他的。posix-extended可能足够理智:

$ touch hello $'new\nline'
$ find . -type f -regex '.*'
./hello
$ find . -type f -regextype posix-extended -regex '.*'
./hello
./new?line

如果您正在跑步其他跑步find,您的里程可能会有所不同。经过快速测试,我的 Mac 上的默认情况下确实会匹配换行符.

再说一次,对于简单的模式,您可以只使用-namewhich 采用 shell 全局变量(并且不应该有换行符问题)。

(?s)看起来像是 PCRE/Perl 正则表达式的一个功能,但我不认为find支持这一点。至于/.*/s,find仅采用原始模式,没有分隔符,因此没有尾随选项。

答案2

命令

find ~user

会找到所有名称,包括那些包含换行符的名称。-type f如果您只想查找常规文件,请添加。

如果您不想限制名称匹配,请不要对名称使用测试。

要限制使用子字符串匹配的名称,您可以在-name测试中使用通配模式。*和都?以通配模式匹配换行符,无论是在一般 shell 中还是在-name的测试中find

使用标准的示例find

$ find . -name 'file?name'
./file
name
$ find . -name 'file*name'
./file
name
$ find . -name 'd*name'
./dir
name
$ echo ./d*name
./dir
name

回答被误解的问题(“如何找到包含换行符的名称”):

使用标准find

find ~user -name '*
*'

在支持这些的 shell 中使用“C-strings”(仍然使用标准find

find ~user -name $'*\n*'

GNU 中通常可用的内置正则表达式类型都无法find将换行符与 相匹配\n,因此您只能使用文字换行符,就像上面的通配模式一样。这意味着使用标准-name测试可能比非便携式-regex测试更容易。

相关内容