2つの特定のファイルを含むサブディレクトリのみを一覧表示

2つの特定のファイルを含むサブディレクトリのみを一覧表示

私は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と同じフォルダにあります)結果が表示されるように検索これら2つのファイルのみを含むフォルダ

事前にありがとう

答え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' ;

この問題を解決するもう1つの方法は、長い間標準でコアであったモジュールを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)

これら2つのファイルを含むディレクトリの最後の2つのコンポーネントを印刷します。

または、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スクリプトにパイプされます。すべての入力が処理された後、2回見たディレクトリを印刷します。

これはfind次のコマンドによって異なります。いいえ1回未満または2回以上パス名を出力します。一致する場合は一度、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
         }
       }'

関連情報