2017-01-17 2 views
0

짧은 버전 :목록 디렉토리

내가 존재 및/또는 특정 파일의 유무에 따라 하위 디렉토리의 목록을 생성하는 bash는 명령을 쓰기 위해 노력하고있어 . 디렉토리 이름에 "Ready"라는 파일이 있고 "Complete"또는 "Failed"라는 파일이없는 경우 목록에 포함됩니다. 나는 여기서 본 예제를 기반으로 '찾기'명령을 사용하여 주변을 둘러 보았지만 실제로 작동하게하려면 일반적으로 충분히 이해하지 못했습니다.

find . -maxdepth 1 -name Ready | find -mindepth 1 -maxdepth 1 -type d '!' -exec test -e "{}/Complete" ';' -print | find -mindepth 1 -maxdepth 1 -type d '!' -exec test -e "{}/Failed" ';' -print 

긴 버전 : 우리의 시스템에서

다른 그룹은 파일의 디렉토리 우리의 응용 프로그램 중 하나에 의해 처리됩니다 ("번들")를 내려. 이 디렉토리에는 번들의 처리 준비 ("준비") 또는 성공적으로 처리 ("완료")되었거나 이전에 오류 ("실패" ").

대부분의 시스템은 소프트웨어이며, 자체 개발 한 모니터링, 관리 및 메트릭 수집 도구를 개발하기 시작했습니다. 주어진 시간에이 디렉토리를보고 상태 파일의 유무에 따라 처리 할 준비가되어 있고 무시 될 스크립트를 작성하려고합니다.

+0

'find '에'find'를 파이핑하는 것은 의미가 없습니다. 대신 여러 개의'-exec' 명령문과 함께 하나의'find'를 사용하십시오. –

답변

1

bash 4 이상을 사용한다고 가정하면 find을 건너 뛰고 재귀적인 glob **/*/을 반복합니다. 당신은 특정 not 일치하는 옵션 find을 사용할 수

for f in **/*/Ready; do 
    d=${f%Ready} 
    [[ -e $d/Completed || -e $d/Failed ]] || printf '%s\n' "$d" 
done 
+0

꽤 잘 작동합니다. 한 가지 문제 - 데이터 보관 정책을 구현하기 전까지 하위 디렉토리에 파일이 많아 반복되는 경우가 많으므로 빠른 유틸리티를 원하는 것보다 스크립트가 오래 실행될 수 있습니다. 우리는 시작 지점에서 한 디렉토리 레벨을 내려다 볼 필요가 있습니다. 그 아래의 항목은 무시할 수 있습니다. 어떻게 할 수 있니? – MrLuckypants

+0

그 경우,'**/*'대신'*/* /'를 사용할 수 있으며'globstar' 옵션은 필요하지 않습니다 (그리고 이것은'bash'의 모든 버전에서 작동합니다. 4+). – chepner

+0

"globstar"옵션을 제거하고 하나의 "*"를 사용하면 나에게 적합합니다 (*/* /하지 않았습니다). 도와 줘서 고마워! – MrLuckypants

0

:

shopt -s globstar nullglob 
for d in **/*/; do 
    [[ -e $d/Ready ]] || continue # Skip directories without a Ready file 
    [[ -e $d/Completed ]] && continue # Skip directories with a Completed file 
    [[ -e $d/Failed ]] && continue # Skip directories with a Failed file 
    print '%s\n' "$d" # If you made it this far, print the directory name 
done 

이 당신은 양자 택일 Ready을 포함하는 디렉토리를 식별 할 글로브를 사용할 수

shopt -s globstar nullglob 
for d in **/*/; do 
    [[ -e $d/Ready && ! (-e $d/Completed || -e $d/Failed) ]] && printf '%s\n' "$d" 
done 

에 응축 될 수있다 이름 :

find . -maxdepth 2 -path "*Ready*" ! -name "Failed" -a ! \ 
-name "Complete" -exec bash -c 'echo "$0"' {} \; 

중첩 된 디렉토리 -path은 (!) "실패"또는 "완료"가 포함되지 않은 "준비된"디렉토리 내의 파일 만 찾습니다. 예를 들어 상위 디렉토리에서 위의 find 명령을 사용하여

$ ls 
Complete Failed Ready outdir sub1  sub2  sub3 

$ cd Ready ; ls 
Complete Failed Ready somefile 

생산하는 것 :

./Ready 
./Ready/Ready 
./Ready/somefile 

당신이 -name-path을 전환 한 경우 당신은 얻을 것이다 :

./Ready 
./Ready/Ready 

find은 강력하다 검색과 관련하여 거의 모든 필요에 맞게 조정할 수있는 유틸리티입니다.

0

다음은 간단한 설명입니다.

트리거로 사용하는 파일을 찾는 find 명령으로 시작하십시오.파일 이름을 제거하는 "그렙"로, 정렬, 중복을 제거 파이프처럼 뭔가 :

find . -type f -name Ready -o -name Completed -o -name Failed | grep -o "^.*/" | sort | uniq 

1 개 수준에 깊이를 매우 제한하는 -type f 이전 -maxdepth 2 -mindepth 2를 추가합니다.