文字列に同じ名前の文字を含むファイルのサブディレクトリを一覧表示して計算します。

文字列に同じ名前の文字を含むファイルのサブディレクトリを一覧表示して計算します。

これを想像してください。

 |-Main_folder
 |- Folder1
    |- E_1
      |- E_1_A
        |- file_E_1_A_F_1
        |- file2_E_1_A_F_2
        |- file3_E_1_A_F_3
      |- E_1_B
        |- file1_E_1_B_F_1
        |- file2_E_1_B_F_2
        |- file3_E_1_B_F_3
    |- E_2
      |- E_2_A
        |- file_E_2_A_M_1
        |- file2_E_2_A_M_2
        |- file3_E_2_A_M_3
      |- E_2_B
        |- file1_E_2_B_M_1
        |- file2_E_2_B_M_2
        |- file3_E_2_B_M_3
    |- E_3
    |...
 |- Folder2

特定の名前のファイルを含むこのようなサブディレクトリ構造があります。 UnixやPythonの「F」文字など、サブディレクトリに「F」文字を含むファイルを含む「E_NUMBER」という名前のサブディレクトリとサブディレクトリの数を確認するのに役立ちます。

どんな助けでも歓迎します。ありがとうございます!

答え1

GNUユーティリティの使用:

(export LC_ALL=C
find Main_folder -name '*F*' -print0 |
  grep -zPo '.*/E_\d+(?=/.*F[^/]*$)' |
  sort -z |
  uniq -zc |
  tr '\0' '\n'
)

このようなファイルMain_folder/Folder1/E_1/whatever/E_2/whatever/xFyは。E_2E_1

これにより、zsh次のことができます。

for dir ( Main_folder/**/E_<->(ND/) ) {
  files=( $dir/**/*F*(ND) )
  if (( $#files )) print -r "$#files *F* files below $dir"
}

上記の例では、ファイルは合計に含まれていますE_1E_2

匿名関数を使用して短縮します。

for dir (Main_folder/**/E_<->(ND/)) () {
  if (($#)) print -r "$# *F* files below $dir"
} $dir/**/*F*(ND)

ディレクトリパスのみが必要で、ここに含まれるファイルの数は気にしない場合は、sort -z | uniq -zcwithsort -zuまたはコマンドをprintwithに置き換えます。print -r $dirF

答え2

「Unixで」という言葉がどういう意味なのかよくわかりません。最も近いシェルが動作する場合は、bash試してみてください。

readarray -t FN <<< $(find .)
for i in "${FN[@]}"
  do    if [[ "${i%/*}" =~ E_[[:digit:]] && "${i##*/}" =~ F ]]
          then  echo "${i%/*}"
        fi
      done | uniq -c

  3 ./E_1/E_1_A
  3 ./E_1/E_1_B

forループがファイル/ディレクトリ名(スペースなど)をブロックしないように、ディレクトリツリーを配列に読み込みます(ただし改行には役立ちません)。E_[[:digit:]]そのファイル名が一致するパス(正規表現に変換された「E_NUMBER」)に含まれている場合にコマンドによって計算されるパス名F。出力が順番にならない場合。echouniqfindsortuniq

関連情報