일치하는 파일이 포함된 모든 디렉터리를 찾는 방법은 무엇입니까?

일치하는 파일이 포함된 모든 디렉터리를 찾는 방법은 무엇입니까?

패턴과 일치하는 파일이 포함된 디렉터리를 찾고 있습니다. 예를 들어 foobar*.csv이러한 파일이 포함된 디렉터리에는 수백 개가 포함될 수 있습니다.하위 디렉터리 없음! ), 그래서 find가 발견되는 즉시 인쇄 here/is/the/path/to/dir하고 here/is/the/path/to/dir/foobar-2022-01-01.csv하강을 중지하고 싶습니다.

어떻게 해야 하나요?

답변1

find /path/to/base/dir -type f -name "foobar*.csv" -exec dirname {} \; | sort -u

설명하다:

  • "foobar*.csv" 패턴과 일치하는 모든 파일을 찾습니다.
  • 각 파일의 디렉터리 이름을 가져옵니다.
  • 고유하게 정렬하세요.

이렇게 하면 메모리가 절약되지 않지만 "수백" 개의 파일에 대해 결과를 얻는 데 몇 밀리초가 걸립니다.

답변2

zsh 사용:

dirs=( **/*(/e['()(($#)) $REPLY/foobar*.csv(NY1)']) )

일치하는 디렉토리의 하위 디렉토리를 찾으려고 계속 시도하고 Y1첫 번째 일치에서 중지되기 때문에 하강이 중지되지는 않지만 foobar*.csvzsh는 하위 디렉토리를 찾기 위해 여전히 모든 (숨겨지지 않은) 디렉토리의 전체 내용을 읽어야 합니다.

답변3

사용(POSIX와 유사)bosh껍데기, 이는 find(실제로sfind)이 내장되어 있으며 쉘 코드를 평가할 수 있는 몇 가지 조건자/조건자가 있습니다 -call.-calldir

find_match() {
  find . ! -name . -prune -name "$1" -call 'pwd; return' ';'
  false
}
find . -type d -calldir 'find_match "foobar*.csv"' ';' -prune

일치하는 디렉터리에 대해 작업을 수행하려면 다음을 추가하세요.

-call '
  dir=$1
  whatever you need to do with "$dir"
' {} ';'

위의 명령에 대해.

-prunefind표준 과 마찬가지로 find하위 디렉터리로 내려가는 것은 차단됩니다. AFAICT, GNU 풍미 또는 NetBSD 풍미는 sfind없지만 함수 내의 피호출자 로부터 호출 하면 동일한 효과를 얻고 더 유연해집니다.-quit-exec [status]return-call[dir]

답변4

대신 finds 옵션을 사용하십시오 .-execdir-exec

find . -iname 'foobar*.csv' -execdir sh -c 'pwd' {} +

이것은 파일 이름 인수가 허용되지 않고 주어지면 불평을 하기 때문에 sh -c래퍼 pwd(단순히 실행하는 대신 -execdir pwd {} +)를 사용합니다. pwd쉘 래퍼를 사용하면 파일 이름 인수를 전달하지 않고도 디렉토리에서 pwd를 실행할 수 있습니다.

또는 디렉터리에서 일치하는 파일 수가 ARG_MAX 수(Linux에서는 약 2MB이므로 그럴 가능성이 낮음)를 초과할 수 있는 경우 출력을 uniq.

find . -iname 'foobar*.csv' -execdir sh -c 'pwd' {} + | uniq

참고: -execdir이는 POSIX 명령에 대한 비표준 개선 사항입니다 find. 일부 버전 find(특히 오래된 버전 및/또는 독점 버전) 에서는 누락되었을 수 있습니다 . 그것GNU 찾기와 BSD 찾기 모두에서 사용할 수 있습니다.

관련 정보