내부에 주어진 파일 이름을 가진 파일이 없는 모든 디렉터리를 나열합니다.

내부에 주어진 파일 이름을 가진 파일이 없는 모든 디렉터리를 나열합니다.

다음을 수행하는 모든 디렉토리를 나열하려면 어떻게 해야 합니까?~ 아니다내부에 주어진 파일 이름을 가진 파일이 있습니까? 예를 들어 이 트리가 주어졌을 때

/
  /a
     README
     file001
     file002
  /b
     README
     file001
  /c
     file003

나는 그 일을 하는 디렉토리를 나열하고 싶다.~ 아니다라는 파일이 있습니다 README. 이 경우에는 디렉토리가 됩니다 /c. 어떻게 해야 합니까? 예를 들어 어떤 구문도 생각할 수 없습니다 find.

답변1

인수에 포함된 값 을 허용하는 findGNU와 같은 구현을 가정하면 다음과 같습니다 .find{}-exec

$ find . -type d \! -exec test -e '{}/README' \; -print

또는 문제가 있는 삽입 없이:

$ find . -type d ! -exec sh -c 'test -e "$1"/README' sh {} \; -print

여기서 1/1부터 5/5까지의 디렉토리에는 README가 있고 다른 디렉토리는 비어 있습니다.

$ tree 
.
|-- 1
|   `-- 1
|       `-- README
|-- 10
|   `-- 10
|-- 2
|   `-- 2
|       `-- README
|-- 3
|   `-- 3
|       `-- README
|-- 4
|   `-- 4
|       `-- README
|-- 5
|   `-- 5
|       `-- README
|-- 6
|   `-- 6
|-- 7
|   `-- 7
|-- 8
|   `-- 8
`-- 9
    `-- 9

이제 이 버전의 명령을 실행하면 다음과 같습니다 find.

$ find . -type d \! -exec test -e '{}/README' \; -print
.
./10
./10/10
./7
./7/7
./9
./9/9
./6
./6/6
./5
./8
./8/8
./4
./1
./3
./2

참고자료

답변2

. find​그냥 쉘을 사용하세요:

for d in */; do [ -f "$d"README ] || printf '%s\n' "$d"; done
c/

재귀적이어야 하는 경우 다음을 사용할 수 있습니다( 의 경우 bash기본적 zsh으로 이 작업을 수행할 수 있으며 set -o globstarin 에서 사용 ksh93).

shopt -s globstar
for d in **/; do [ -f "$d"README ] || printf '%s\n' "$d"; done

(도트 파일은 기본적으로 제외됩니다.)

답변3

-exec옵션을 사용하여 find파일을 확인한 다음 확인에 실패한 모든 결과를 인쇄 할 수 있습니다 .

find /path/to/base -mindepth 1 -maxdepth 1 -type d -exec test -e {}/README \; -o -print

답변4

이식 가능한 방법은 다음과 같습니다.

find . -type d -exec sh -c '
  for dir do
    [ -f "$dir/README" ] || printf "%s\n" "$dir"
  done' sh '{}' +

[ -f file ]파일이 있는지 테스트존재한다 그리고일반 파일인 것으로 확인되었습니다(심볼릭 링크 확인 후).

유형에 관계없이 해당 디렉토리의 항목으로만 존재하는지 테스트하려면 다음이 필요합니다. [ -e file ] || [ -L file ]단, 해당 테스트를 수행하려면 디렉토리에 대한 검색 권한이 필요합니다. [ -x "$dir" ]다음과 같은 경우를 설명하기 위해 몇 가지 테스트를 추가할 수 있습니다 .

find . -type d -exec sh -c '
  for dir do
    if [ -x "$dir" ]; then
      [ -f "$dir/README" ] || printf "%s\n" "$dir"
    else
      printf >&2 "Cannot tell for \"%s\"\n" "$dir"
    fi
  done' sh '{}' +

또는 경쟁 조건을 피하려면 다음을 사용하십시오 zsh.

find . -type d -exec zsh -c '
  zmodload zsh/system
  for dir do
    ERRNO=0
    if [ ! -f "$dir/README" ]; then
      if [ "$errnos[ERRNO]" = ENOENT ]; then
        printf "%s\n" "$dir"
      else
        syserror -p "ERROR: $dir/README: "
      fi
    fi
  done' zsh '{}' +

또한보십시오Bash에 일반 파일이 없는지 어떻게 알 수 있나요?그래서.

관련 정보