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'

findコマンドにperl正規表現エンジンを追加する方法はありますか?

私はそれを基本的なfindで使用したいと思います。 findの出力をgrepや他のプログラムにパイプしたくありません。

答え1

1つのプロセスのみを使用する1つの方法は、純粋なパールそして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 …

ここで... ファイルをディスクに書き込むだけで十分でない場合、ファイルとして何をするのですか?

perlGNUの代わりに以前のバージョンのGNU APIに基づいて(または少し移植性の高いBSDの場合)grep使用できます。grep -zPgrep --null -Pgrepgrep

find . -regextype perl -regex 'some perl regexp' -exec cmd {} +kshスタイルのプロセス置換をサポートするシェルを使用して、仮想に近いものは次のとおりです。

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

標準入力を-exec cmd {} +保持するのと同じです。パイプcmd<(...)まだ使用されています。

デフォルトではperlバイト単位で動作しますが、find/はgrep文字単位で動作することを好みます。-Cあるいは、オプションは、-Mopen=locale一致する前にバイトを文字としてデコードするのに役立ちます。

-print0、、、、、、、、は非標準のGNU拡張であり、現在他のほとんどの実装で見つかって-r-0ます。 (ファイルが見つからない場合はコマンドを実行しないでください)も一般的です。 (not) で、デフォルトの正規表現構文は実装ごとに異なります。-a-z-P-regex-regex-type-print0-0-r-regex-regex-type

答え3

まったくそうではありません。またはむしろそうです。可能しかし、直接プログラムする必要があります。findサポートしている実装が見つからない限りPCRE、私は個人的にはよく分からない。唯一のオプションは直接コーディングすることです。

使用しているプログラムに必要な機能がない場合、唯一のオプションは開発者にその機能を実装するように依頼し、実装することを望むか、コードを直接書くことです。私たちのほとんどは、このようなツールの機能を拡張するために必要な知識がないので、残念ながら、findあなたの質問に対する答えは基本的に「いいえ」です。

答え4

次のように動作します(正規表現はファイル名だけでなく、フルパスも一致します)。

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

関連情報