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

하나의 프로세스만 사용하는 한 가지 방법은순수 펄그리고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, -r, -0, -a, -z, -P, 는 비표준 GNU 확장이며 현재 대부분의 다른 구현에서 발견 -regex됩니다 . (파일을 찾을 수 없으면 명령을 실행하지 마십시오)도 일반적입니다. (not)이며 기본 정규식 구문은 구현마다 다릅니다.-regex-type-print0-0-r-regex-regex-type

답변3

전혀 그렇지 않다. 아니면 오히려 그렇습니다가능한, 하지만 직접 프로그래밍해야 합니다. find지원하는 구현을 찾지 않는 한PCRE, 저는 개인적으로 잘 모르겠습니다. 유일한 옵션은 직접 코딩하는 것입니다.

사용 중인 프로그램에 필요한 기능이 없는 경우 유일한 옵션은 개발자에게 해당 기능을 구현하도록 요청하고 구현하기를 바라거나 코드를 직접 작성하는 것입니다. 우리 대부분은 이와 같은 도구의 기능을 확장하는 데 필요한 지식이 없기 때문에 find유감스럽게도 귀하의 질문에 대한 대답은 기본적으로 "아니요"입니다.

답변4

다음과 같은 것이 작동합니다(정규식은 파일 이름뿐만 아니라 전체 경로도 일치합니다).

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

관련 정보