와일드카드를 사용하여 -exec 찾기

와일드카드를 사용하여 -exec 찾기

bash 'find'를 사용하여 .log 파일이 포함된 모든 폴더를 처리하고 크기를 얻으려고 합니다. 그러나 와일드카드가 예상대로 작동하지 않습니다. 이는 아무것도 반환하지 않습니다.

find . -type d -exec test -e '{}/*.log' \; -exec du -d0 '{}' \;

*.log그러나 으로 바꾸면 foo.log해당 파일 이름이 포함된 디렉터리에 대해 예상대로 작동합니다.

유사한 SE 게시물을 기반으로 다음을 시도했습니다.

find . -type d -exec bash -c 'test -e "{}/*.log"' \; -exec du -d0 '{}' \;
find . -type d -exec bash -c 'test -e "$1/*.log"' '{}' \; -exec du -d0 '{}' \;

하지만 그건 더 이상 작동하지 않습니다.

답변1

to 와 find … -exec test -e '{}/*.log'같은 문자열을 전달하면 어디에 있습니까 ?something/*.logtest*오자. 두 도구 모두 이를 와일드카드로 처리하지 않습니다. 일부 구현은 인수의 일부인 경우( 전체 인수가 아닌) find확장조차 하지 않습니다 .{}{}

이후 시도 중 하나가 {}셸 코드에 포함됩니다.{}쉘 코드에 절대로 포함하지 마십시오.. 이 문제에 있어서는 다른 시도가 더 낫습니다. 해결책에 가까워졌습니다. 이것은일하다:

# still flawed though
find . -type d -exec bash -c 'test -e "$1/"*.log' bash '{}' \; -exec du -d0 '{}' \;

보다의 두 번째 sh는 무엇입니까 sh -c 'some shell code' sh?. 그러나 주요 "수정"은 쉘 코드에서 별표를 인용하지 않는 것입니다. 이렇게 하면 내부 쉘의 와일드카드가 됩니다(그러나 외부 쉘에서는 그렇지 않고 적절하게 작은따옴표로 묶여 있습니다). 문제는 *.log두 단어 이상으로 확장될 수 있으며(일치하는 파일이 많은 경우) 이 경우 test호출이 중단된다는 것입니다.

다음 코드는 파일이 있는 디렉터리를 찾습니다 *.log.

find . -type d -exec sh -c '
   for f in "$1/"*.log; do test -e "$f" && exit 0; done; exit 1
' sh {} \; -print

코드는 이식 가능합니다. inner 가 필요하지 않으며 bashsh빨라야 합니다. 원할 경우 -print로 교체하세요 .-exec du …

이는 일치하는 파일의 존재를 확인 exit 0하자마자 내부 쉘에서 성공( )을 반환함으로써 작동합니다 . test아직 테스트되지 않은 일치 파일(있는 경우)은 헛되이 테스트되지 않으므로 시간이 절약됩니다. 일치하는 항목이 없으면 패턴은 그대로 유지되고 test실패하며 전체 쉘은 실패( exit 1)와 함께 종료됩니다. 기억하는 것도 -exec테스트이므로 수행 여부 -print(또는 -exec du …거기에 입력한 항목)에 영향을 미칩니다.


find또 다른 접근 방식은 다음과 일치하는 파일을 스스로 찾도록 하는 것입니다 .

find . -name '*.log' … -print

출력을 구문 분석하여 디렉토리 이름을 분리하고 마지막 xargs으로 du. 디렉토리는 여러 번 나타날 수 있으며 경로 이름의 줄 바꿈에는 이식할 수 없는 코드( 에서 시작 -print0)가 필요합니다. 제 생각에는 이것이 불필요하게 복잡할 것 같습니다. 디렉토리를 찾는 것이 더 나은 것 같습니다.


¹ 메모는 test -e파일이 있는지 알려줍니다.디렉토리나 무엇이든 될 수 있습니다.. 일반 파일이 있는지 확인하려면 test -f.

답변2

로그 파일을 찾거나 스캔한 다음 고유한 디렉터리 이름을 수집하는 것이 더 쉬울 것입니다.

find명령은 디렉터리를 가져와서 uniq중복 항목을 제거해야 합니다. -z/ 플래그 -0는 개행/공백/따옴표가 있는 경로 이름이 완벽하게 구문 분석되도록 도와줍니다.

find . -type f -name \*.log -exec dirname -z {} \+ | uniq -z | xargs -0 -r du -d0

| sort -rn |head가장 큰 디스크 사용량을 검색하는 경우 추가하세요 .

관련 정보