지정된 파일 이름을 가진 파일이없는 모든 디렉토리를 나열하십시오.


12

주어진 파일 이름을 가진 파일 이 없는 모든 디렉토리를 어떻게 나열 합니까? 예를 들어이 트리가 주어지면

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

파일 이름 이 없는 디렉토리를 나열하고 싶습니다 README.이 경우 디렉토리가 /c됩니다. 어떻게해야합니까? eg 사용하는 구문을 생각할 수 없습니다 find.


수치심 당신이 검색조차하지 수치심 : askubuntu.com/questions/196960/…
slm

검색 할 때 올바른 키워드를 생각하지 못했습니다.
Renan

2
난 그냥 당신의 절단에 바스 트입니다. 나는 여러 번 거기에 있었는데 8-)를 검색하기에 적합한 단어를 생각할 수 없었습니다.
slm

답변:


5

다음 find과 같은 인수로 임베디드 find를 허용하는 GNU와 같은 구현을 가정합니다 .{}-exec

$ find . -type d \! -exec test -e '{}/README' \; -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

참고 문헌


특정 파일 확장자가없는 하위 디렉토리 (예 : * .txt)를 검색하도록 명령을 수정하는 방법 * .txt로 README를 수정해도 작동하지 않는 것
WanderingMind

@WanderingMind-새로운 질문이 있으시면 사이트에 새 질문으로 문의하십시오 ;-)
slm

3

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

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

3

필요 없습니다 find. 쉘을 사용하십시오.

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

당신이 재귀 적으로 필요한 경우 (들어, 당신이 사용할 수있는 bash, zsh기본적를 사용하여이 작업을 수행 할 수 set -o globstar있는 ksh93) :

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

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


2

with zshglob 한정자 ( estring ) :

print -rl -- *(/e_'[[ ! -f $REPLY/README ]]'_)

또는

print -rl -- *(/^e_'[[ -f $REPLY/README ]]'_)

D숨겨진 디렉토리를 포함하도록 추가하십시오 .

print -rl -- *(D/e_'[[ ! -f $REPLY/README ]]'_)

/디렉토리 만 e_'[[ ! -f $REPLY/README ]]'_선택하고 따옴표 사이의 쉘 코드가 리턴하는 디렉토리 이름 만 선택합니다. 즉, glob가 확장되는 true각 디렉토리 이름 ( $REPLY)에 대해 결과가있는 경우 디렉토리 이름을 *(/)실행 [[ ! -f $REPLY/README ]]하고 유지합니다 true.
두 번째 형식 ^e_'.....'_은 동일한 glob 한정자를 사용합니다 (이번에는 조건식이 무시되지 않습니다 [[ -f $REPLY/README ]]).


위의 내용은 현재 디렉토리의 디렉토리 이름 만 반환합니다.
재귀 적으로 검색하려면 (숨겨진 디렉토리를 포함하려면 D규정 자를 추가하십시오 ) :

print -rl ./**/*(/e_'[[ ! -f $REPLY/README ]]'_)

2

다행스럽게도 다음을 수행 할 수 있습니다.

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

[ -f file ]파일 이 존재 하고 일반 파일임을 확인합니다 (symlink 확인 후).

유형에 관계없이 해당 디렉토리의 항목으로 만 존재하는지 테스트하려면 다음 [ -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 '{}' +

참조 일반 파일이 배쉬에 존재하지 않는 경우 어떻게 알 수 있습니까? 그래서.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.