특정 결말을 가진 파일이없는 디렉토리 찾기


10

특정 파일 끝을 가진 파일을 포함하지 않는 모든 디렉토리를 표시하고 싶습니다. 따라서 다음 코드를 사용해 보았습니다.

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

이 예제에서는 ending 파일을 포함하지 않는 모든 디렉토리를 표시하고 .ENDING싶지만 작동하지 않습니다.

내 실수는 어디입니까?


이 질문은 와일드 카드를 처리하지 않기 때문에 파일을 포함하지 않는 List 디렉토리 의 복제본 이 아닙니다.
Cristian Ciupitu

답변:


7

다음은 세 단계로 구성된 솔루션입니다.

temeraire:tmp jenny$ find . -type f -name \*ENDING -exec dirname {} \; |sort -u > /tmp/ending.lst
temeraire:tmp jenny$ find . -type d |sort -u > /tmp/dirs.lst
temeraire:tmp jenny$ comm -3 /tmp/dirs.lst /tmp/ending.lst 

2
Bash 쉘을 사용하는 경우 임시 파일이없는 하나의 라이너 :comm -3 <(find . -type f -name \*ENDING -exec dirname {} \; |sort -u) <(find . -type d |sort -u)
Cristian Ciupitu

4

우리는 간다!

#!/usr/bin/env python3
import os

for curdir,dirnames,filenames in os.walk('.'):
  if len(tuple(filter(lambda x: x.endswith('.ENDING'), filenames))) == 0:
    print(curdir)

또는 교대로 (그리고 더 많은 파이썬) :

#!/usr/bin/env python3
import os

for curdir,dirnames,filenames in os.walk('.'):
    # Props to Cristian Cliupitu for the better python
    if not any(x.endswith('.ENDING') for x in filenames):
        print(curdir)

보너스 DLC 컨텐츠!

find 명령의 (대부분) 수정 된 버전 :

find . -type d \! -exec bash -c 'set nullglob; test -f "{}"/*.ENDING' \; -print

디렉토리에 여러 파일 이 있으면 찾기 솔루션이 실패 한다고 생각합니다 . test: ...: binary operator expected*.ENDING
Cristian Ciupitu

next(filter(lambda x: x.endswith('.ENDING'), filenames))또한 생성자 이해를 사용하여 작성할 수 있습니다 next(x for x in filenames if x.endswith('.ENDING')).
Cristian Ciupitu

@CristianCiupitu : 진실 : find 명령은 해킹되어 완전히 테스트되지 않았습니다. 제너레이터 이해-그래, 또 다른 좋은 방법이다.
MikeyB

1
나는 빈 iterable에 대한 if not any(x.endswith('.ENDING') for x in filenames)리턴이 있다는 사실에 기초하여 더 좋은 해결책을 사용하는 것이 될 것이라고 생각합니다 False.
Cristian Ciupitu

3

쉘은을 확장 *하지만 귀하의 경우 쉘이 없으며 find 명령으로 실행되는 테스트 명령 만 있습니다. 따라서 존재 여부를 테스트 한 파일의 이름은 그대로 입니다.*.ENDING

대신 다음과 같은 것을 사용해야합니다.

find . -type d \! -execdir sh -c 'test -e {}/*.ENDING' \; -print

이로 인해 테스트 가 실행될 때 sh가 확장 *.ENDING됩니다 .

출처 : UX.SE에서 globbing 찾기


작동하지 않습니다. 다음과 같은 오류가 발생합니다 : sh : -c: line 0: syntax error near unexpected token ( '`. 내 디렉토리 이름은'xyz (dfdf) '형식입니다. 실제로는 그 라이브러리입니다.
bamboo

1
시도 sh: line 0: test: foo1/bar.ENDING: binary operator expected하면 끝이있는 파일이 들어있는 디렉토리를 얻 습니다 ENDING.
Jenny D

이것은 일반 a와 함께 작동하는 것 같습니다 .ENDING filenames
user9517

다음 테스트 디렉토리 구조가 있습니다 : test-> test (test)-> test.ending이 코드를 사용한 후 sh: -c: line 0: syntax error near unexpected token ( 'sh : -c : line 0 :'test -e test (test) / *. ending '을 얻습니다 . / test (test)`.하지만 .ending을 .xyz로 변경하면 같은 결과가 나타납니다. 이것은 디렉토리 이름으로 포가 있기 때문입니다. 어떻게 고칠 수 있습니까?
bamboo

3
@bamboo 나는 쉘 유틸리티를 포기 하고이 시점에서 다른 솔루션을 찾습니다.
user9517

2

Dennis NolteMikeyB의 답변에서 영감을 얻은 이 솔루션을 생각해 냈습니다.

find . -type d                                                           \
  \! -exec bash -c 'shopt -s failglob; echo "{}"/*.ENDING >/dev/null' \; \
  -print 2>/dev/null

그것은 사실에 근거하여 작동합니다

경우 failglob의 쉘 옵션을 설정하고, 더 일치가 발견되지 않는 오류 메시지가 인쇄되고, 명령이 실행되지 않습니다.

그건 그렇고, 그래서 stderr 이 (으)로 리디렉션되었습니다 /dev/null.


1

개인적으로 펄에서하겠습니다

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;


#this sub is called by 'find' on each file it traverses. 
sub checkdir {
    #skip non directories. 
    return unless ( -d $File::Find::name );

    #glob will return an empty array if no files math - which evaluates as 'false'
    if ( not glob ( "$File::Find::name/*.ENDING" ) ) {
        print "$File::Find::name does not contain any files that end with '.ENDING'\n";
    }
}

#kick off the search on '.' - set a directory path or list of directories to taste.
#  - you can specify multiple in a list if you so desire. 
find (  \&checkdir, "." );

트릭을 수행해야합니다 (매우 간단한 테스트 사례에서 작동).


0

여기에 하나의 라이너가 있습니다.

find ./ -type d ! -regex '.*.ENDING$' -printf "%h\n" | sort -u

편집 : 죄송합니다, 작동하지 않습니다.


내부의 파일이 아닌 디렉토리의 이름을 테스트하기 때문에 작동하지 않습니다.
Cristian Ciupitu

나는 그것을 다시 시도했다. 심하게
매튜 Ife

0
find . -type d '!' -exec sh -c 'ls -1 "{}"|egrep -q "*ENDING$"' ';' -print
  • q egrep에서 조용합니다

  • 으로 egrep당신은 당신이 필요로하는 정규식을 교환 할 수 있습니다

  • ls -1 "{}" find 명령에서 파일 이름을 출력합니다

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