我想在使用 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
仅使用一个进程的一种方法是仅使用纯Perl和File::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 …
其中...是如果仅将文件写入磁盘还不够的话,您对文件执行的操作。
除了perl
GNU 之外grep
,您还可以使用grep -zP
(或者对于某些基于旧版本 GNU 的 API 的 BSD 来说,grep --null -P
稍微更便携)。grep
grep
与假设的 更接近的等效项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.$'