찾기: 슬래시의 특수 처리

찾기: 슬래시의 특수 처리

경로를 일치시키는 데 사용하고 싶지만 find다음을 발견했습니다.

-path pattern

파일 이름은 쉘 패턴과 일치합니다. 메타문자는 /' or특별히 처리되지 않습니다 . 예를 들어 다음과 같습니다.

  find . -path "./sr*sc"

./src/misc이름이 지정된 디렉토리(존재하는 경우)에 대한 항목이 인쇄됩니다.

현재 디렉터리의 파일만 일치시키려면 어떻게 해야 합니까? 작업을 수행하려면 다른 도구가 필요합니까?

편집하다. 제안된 대로 몇 가지 세부정보는 다음과 같습니다. 작업을 완료하려면 다음이 -maxdepth있습니다 -regex. 그러나 실제 애플리케이션에서는 경로가 단순한 상수가 아닌 변수일 수 있으며, 이는 -maxdepth제대로 작동하지 않고 -regex과잉처럼 보일 수 있습니다. 그래서 슬래시를 존중하도록 만드는 간단한 해결책이 있는지 궁금합니다 find. 다음은 해당 동작을 설명하는 rsync 문서입니다. 이는 제가 원하는 것과 매우 가깝습니다.

현재 가장 좋은 해결책은 정규식을 사용하는 것입니다. 그러나 정규식을 더 간단하게 만드는 방법을 알고 있다면 환영할 것입니다.


내가 원하는 것의 예로서 다음은 rsync 패턴 규칙입니다.

  • '*'는 모든 경로 구성 요소와 일치하지만 슬래시에서 중지됩니다.

  • 슬래시를 포함하여 무엇이든 일치시키려면 "**"를 사용하세요.

답변1

대신 사용하십시오 -regex. 패턴은 시작과 끝이 정해져 있으니 .*시작과 끝 부분에 활용하시면 좋을 것 같습니다. 일치하지 않는 글로브를 교체하는 데 사용됩니다 [^/]*/. 예를 들어:*/

-regex '.*/sr[^/]*sc.*'

작은 Perl 스크립트가 있습니다2펄 찾기명령의 인수를 find동등한 Perl 스크립트로 변환한다고 주장합니다. 분명히 이는 -pathas 와 동일한 패턴 일치를 갖지만 find다른 인수(예 -glob: 시스템 호출을 사용하여 fnmatch()원하는 종류의 와일드카드 지정)를 허용하도록 편집할 수 있습니다. find2perl이 패치에 표시된 대로 내 버전을 빠르게 수정했습니다 .

--- /usr/bin/find2perl  2016-02-04 19:28:48.000000000 +0100
+++ /tmp/find2perl      2018-07-31 20:38:10.034175198 +0200
@@ -58,2 +58,4 @@
     $out .= tab . '$File::Find::name =~ /' . fileglob_to_re(shift) . "/s$1";
+    } elsif (/^glob$/) {
+        $out .= tab . 'fnmatch("'.(shift).'", $name, FNM_PATHNAME|FNM_PERIOD)';
 } elsif ($_ eq 'perm') {
@@ -236,2 +238,3 @@
 use File::Find ();
+use File::FnMatch qw(:fnmatch);    # import everything

(첫 번째 줄에는 +내가 추가한 3줄이 표시됩니다.) Fedora용 perl-App-find2perl패키지를 추가해야 합니다 perl-File-FnMatch. 시스템에서 이에 상응하는 항목을 찾아야 합니다.

그런 다음 다음과 같은 명령을 실행할 수 있습니다.

/tmp/find2perl . -glob './sr*sc' | perl

답변2

find하위 디렉토리로의 재귀를 방지하려면 -maxdepth플래그를 사용하십시오.

find -maxdepth 1 -name "sr*sc"

답변3

및 등의 일부 셸은 zsh파일 이름 글로빙 패턴을 지원합니다. 기본적으로 활성화되어 있으므로 반드시 활성화하고 사용해야 합니다.bashksh93**zshbashshopt -s globstarksh93set -o globstar

즉, 다음을 수행할 수 있어야 합니다.

for pathname in ./src/**/misc/*.c
    # process "$pathname" here
done

예를 들어 일부 find유사한 테스트를 -type f쉽게 통합할 수 있습니다.

for pathname in ./src/**/misc/*.c
    [ -f "$pathname" ] || continue  # will not skip symbolic links to regular files though
    # process "$pathname" here
done

관련 정보