두 개의 특정 파일을 포함하는 하위 디렉터리만 나열

두 개의 특정 파일을 포함하는 하위 디렉터리만 나열

나는 iPhone의 터미널을 사용하여 iOS에서 다음 코드를 실행하고 있으며, 명확히 하기 위해 이 명령은 New Term 2라는 간단한 터미널 조정을 사용하여 탈옥된 iPhone에서 실행됩니다.

cd /var/mobile/Library/Widgets
find . -maxdepth 3 -name 'index.html' -printf "%h\n"

그러면 포함된 폴더 목록이 반환됩니다 index.html. 다른 파일을 추가하는 방법을 알고 싶습니다. ( Config_extra.js존재하는 경우 index.html과 동일한 폴더에 있음) 결과가 표시되는 방식으로 검색에이 두 파일만 포함된 폴더

미리 감사드립니다

답변1

거의 다 왔습니다. index.html 파일을 찾으면 (iOS의 BSD를 포함한 일부 구현에서 지원되는 비 POSIX 옵션)을 통해 동일한 디렉터리에서 Config_extra.js 파일을 찾도록 요청합니다 find. 성공하면 디렉토리 이름을 인쇄합니다.-execdirfindfind

find . -maxdepth 3 -type f -name index.html -execdir test -f Config_extra.js \; -printf '%h\n'

위 명령은 확장된 형식으로 작성되었습니다.

find . -maxdepth 3 \
  -type f -name index.html \
  -execdir test -f Config_extra.js \; \
  -printf '%h\n' ;

이 문제를 해결하는 또 다른 방법은 오랫동안 표준이자 핵심이었던 모듈을 perl사용하는 것 입니다. 의미는, 당신이 가지고 있다면, 당신은 가지고 있다는 것입니다.File::FindPerlperlFile::Find

cfg='Config_extra.js'
perl -MFile::Find -le '
  find(
    sub {
      my $cfg = $ARGV[0];
      my $d = $File::Find::dir;
      -d && "$d/" =~ m|(?:.*/){3}| && $File::Find::prune++;
      -f && /^index\.html$/ && -f $cfg && print($d);
    }, 
    shift,
  )
' . "$cfg"

답변2

당신은 그것을 사용할 수 있습니다 find -exec:

find . -maxdepth 3 -name 'index.html' -exec sh -c '
  [ -f "${f%/*}/Config_extra.js" ]' find-sh {} \; -printf "%h\n"

큰 디렉토리 트리가 있으면 -exec ... +더 잘 작동합니다.

find . -maxdepth 3 -name 'index.html' -exec sh -c '
  for f do
    d="${f%/*}"
    [ -f "$d/Config_extra.js" ] && printf "%s\n" "$d"
  done' find-sh {} +

또는 디렉토리를 검색하십시오.

find . -maxdepth 2 -type d -exec sh -c '
  [ -f "$1/index.html" ] && [ -f "$1/Config_extra.js" ]' find-sh {} \; -print

또는 사용-exec ... +

find . -maxdepth 2 -type d -exec sh -c '
  for d do
    [ -f "$d/index.html" ] && [ -f "$d/Config_extra.js" ] && printf "%s\n" "$d"
  done' find-sh {} +

답변3

쉘이 zsh인 경우 다음을 수행할 수 있습니다.

print -rC1 - /var/mobile/Library/Widgets/*/*(N-/e['
  [[ -e $REPLY/index.html && -e $REPLY/Config_extra.js ]]']:t2)

이 두 파일을 포함하는 디렉터리의 마지막 두 구성 요소를 인쇄합니다.

또는 glob이 있는 파일과 eglob 한정자가 있는 다른 파일을 찾아 2개의 구성 요소를 인쇄합니다.꼬리~의머리다음 파일 중:

print -rC1 - /var/mobile/Library/Widgets/*/*/index.html(Ne['
  [[ -e $REPLY:h/Config_extra.js ]]']:h:t2)

답변4

find . -maxdepth 3 -name index.html -o -name Config_extra.js | 
  perl -lne '($dir,$base) = m:(^.*)/(.*$):;
             $dirs{$dir}++;
             END { foreach (sort keys %dirs) {print if $dirs{$_} == 2} }'

index.htmlfind는 또는 일치하는 파일의 전체 경로 이름을 인쇄합니다 Config_extra.js. 이는 각 디렉토리가 표시된 횟수를 계산하는 Perl 스크립트로 파이프됩니다. 모든 입력이 처리된 후 두 번 본 디렉토리를 인쇄합니다.

이는 find다음 명령 에 따라 달라집니다.안 돼요한 번 미만 또는 두 번 이상 경로 이름을 출력합니다. 일치하는 경우 한 번 index.html및/또는 일치하는 경우 한 번 Config_extra.js.

awk의 알고리즘은 대략 동일합니다.

find . -maxdepth 3 -name index.html -o -name Config_extra.js | 
  awk '{
         sub("/[^/]+$","",$0);
         dirs[$0]++
       }

       END {
         for (i in dirs) {
           if (dirs[i] == 2) print i
         }
       }'

관련 정보