경로를 일치시키는 데 사용하고 싶지만 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 스크립트로 변환한다고 주장합니다. 분명히 이는 -path
as 와 동일한 패턴 일치를 갖지만 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
파일 이름 글로빙 패턴을 지원합니다. 기본적으로 활성화되어 있으므로 반드시 활성화하고 사용해야 합니다.bash
ksh93
**
zsh
bash
shopt -s globstar
ksh93
set -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