Regex 查找命令can';不排除确切的正则表达式

Regex 查找命令can';不排除确切的正则表达式,regex,linux,bash,find,Regex,Linux,Bash,Find,我有以下脚本: #!/bin/bash arg=$1 exclude='(/etc/alternatives/(awk|vim)|/usr/sbin/poweroff)$' find $arg -type f,l,c,b -regextype posix-extended -not -regex "${exclude}" -print 我没有在每个文件的开头使用^,因此可以从任何内容开始。但是我在每个文件的末尾都使用了$ 因此,当我以这种方式运行脚本时,它工作正常: $ s

我有以下脚本:

#!/bin/bash
arg=$1
exclude='(/etc/alternatives/(awk|vim)|/usr/sbin/poweroff)$'
find $arg -type f,l,c,b -regextype posix-extended -not -regex "${exclude}" -print
我没有在每个文件的开头使用
^
,因此可以从任何内容开始。但是我在每个文件的末尾都使用了
$

因此,当我以这种方式运行脚本时,它工作正常:

$ sudo bash script.sh /etc/ | grep awk
/etc/alternatives/nawk
/etc/alternatives/nawk.1.gz
/etc/alternatives/awk.1.gz
但当我这样做的时候,那就是错误:

$ sudo cp -rv /etc/ /tmp/
$ sudo bash script.sh /tmp/etc/ | grep awk
/tmp/etc/alternatives/awk
/tmp/etc/alternatives/nawk
/tmp/etc/alternatives/nawk.1.gz
/tmp/etc/alternatives/awk.1.gz
这里您可以看到文件
/tmp/etc/alternations/awk
,由于缺少
^
符号,因此不应在结果中传递该文件

更新 此模式运行良好,但我想使用上面的模式:

find $arg -type f,l,c,b | grep -Ev "${exclude}"

据我所知,
-regex
测试是GNU实现
find
的一个特性;POSIX没有定义它。无论如何,GNU的实现几乎肯定是您最喜欢的Linux发行版上的实现。有这样的说法:

Test:-regex expr
Test:-iregex expr
如果整个文件 名称与正则表达式expr匹配总的来说这是一场比赛 路径,而不是搜索。[……]

(重点补充)。也就是说,即使模式中没有明确的锚定,测试总是像正则表达式被锚定到行的起始端一样执行。您可以通过在正则表达式前面加上前缀和/或后缀
*
(视情况而定)来解决这个问题

对于您的示例,可能看起来是这样的:

exclude='.*(/etc/alternatives/(awk|vim)|/usr/sbin/poweroff)'

我省略了不必要的尾随锚点,因为这对我来说似乎更清楚,但如果您希望保留它,那么就这样做吧——这没有什么害处。

尝试将-regextype从postix extended更改为posix egrepThank。它正在工作。哪种方法更好
grep-Ev“${exclude}”
-regextype posix extended-not-regex“${exclude}”-print
?@M.J,rhe
grep
版本更具可移植性,但如果您只关心支持具有GNU
find
的系统,那么通过
-regex
只需一个进程就可以轻松完成工作,但是当你的脚本在
/tmp
中并且你想以这种方式运行脚本时:
bash script.sh etc/
它不起作用,并且你总是必须使用绝对路径作为参数。@M.J,它最终打印的路径与正则表达式匹配的路径是相同的。它们以指定给它的起始点目录名开始。我认为这个问题是关于(GNU)
find
-regex
测试的语义,这就是我的答案。我的建议适用于问题中给出的示例。如果您需要帮助调整正则表达式以服务更多的情况,那么这将是另一个问题的主题。因此,我们需要使用
realpath
命令来获取文件绝对路径,以便处理它。非常感谢。