是否可以在 linux find 命令中使用类似 perl 的正则表达式?

是否可以在 linux find 命令中使用类似 perl 的正则表达式?

我想在使用 find 命令搜索文件时使用 find perl 风格的正则表达式。目前似乎不支持此功能。

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

有没有办法将perl正则表达式引擎添加到find命令中?

我想将它与原生 find 一起使用;我不想将 find 的输出通过管道传输到 grep 或其他程序。

答案1

仅使用一个进程的一种方法是仅使用纯PerlFile::Find模块

自 以来,它已包含在核心中perl5,因此您无需安装任何内容:

$ corelist File::Find

Data for 2021-05-20
File::Find was first released with perl 5

有一个find2perl脚本在那里

您可以从常用命令生成 Perl 代码find

find2perl [paths] [predicates] 

前任:

$ find2perl . -type f -name '*l'
#! /usr/bin/perl -w
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
        if 0; #$running_under_some_shell

use strict;
use File::Find ();

# Set the variable $File::Find::dont_use_nlink if you're using AFS,
# since AFS cheats.

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

sub wanted;
   
# Traverse desired filesystems
File::Find::find({wanted => \&wanted}, '.');
exit;

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);

    (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
    -f _ &&                 # -type f
    /^.*l\z/s               # ^.*l$ regex to modify as you want
    && print("$name\n");    # -print
}

现在你有一个根据开始解决。您可以使用自己的正则表达式根据需要修改 Perl 正则表达式。

用法:

find2perl -type f -name '*l' > myPerlFind.pl
chmod +x myPerlFind.pl
$EDITOR myPerlFind.pl
./myPerlFind.pl

您还可以使用@ARGV将参数传递给脚本,甚至更好:Getopt::长

答案2

如果不重写 find ,就无法使用 find 来完成此操作。

您要求没有管道,但没有管道是不可能的。

find . -print0 |
    perl -0ne 'print if /some perl regexp/s' | 
    xargs -r0 …

其中...是如果仅将文件写入磁盘还不够的话,您对文件执行的操作。

除了perlGNU 之外grep,您还可以使用grep -zP(或者对于某些基于旧版本 GNU 的 API 的 BSD 来说,grep --null -P稍微更便携)。grepgrep

与假设的 更接近的等效项find . -regextype perl -regex 'some perl regexp' -exec cmd {} +(带有支持 ksh 样式进程替换的 shell)将是:

xargs -r0a <(
  find . -print0 |
    perl -0ne 'print if /some perl regexp/s') cmd

这就像-exec cmd {} +保留了cmd标准输入。注意<(...)仍然使用管道。

请注意,默认情况下,perl按字节工作,而find/grep倾向于按字符工作。-C或选项-Mopen=locale可以帮助在进行匹配之前将字节解码为字符。

请注意-print0-r-0、 、-a-z-P-regex-regex-type都是非标准 GNU 扩展,现在在大多数其他实现中都可以找到-print0/ 。 (如果没有找到文件则不运行命令)也很常见。(不是)以及默认的正则表达式语法随实现的不同而变化。-0-r-regex-regex-type

答案3

不它不是。或者更确切地说,是的可能的,但需要你自己编程。除非你找到find支持的实现PCRE,我个人不知道,你唯一的选择就是自己编码。

如果您使用的程序没有您需要的功能,您唯一的选择是要求开发人员实现它并希望他们实现,或者自己编写代码。由于我们大多数人都没有必要的知识来扩展像 这样的工具的功能find,我担心你的问题的答案基本上是“不”。

答案4

像这样的东西是有效的(正则表达式不仅匹配文件名,还匹配完整路径):

find tmp/ -regex '.*pack.ge.jso.$'

相关内容