これを想像してください。
|-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_2
E_1
これにより、zsh
次のことができます。
for dir ( Main_folder/**/E_<->(ND/) ) {
files=( $dir/**/*F*(ND) )
if (( $#files )) print -r "$#files *F* files below $dir"
}
上記の例では、ファイルは合計に含まれていますE_1
。E_2
匿名関数を使用して短縮します。
for dir (Main_folder/**/E_<->(ND/)) () {
if (($#)) print -r "$# *F* files below $dir"
} $dir/**/*F*(ND)
ディレクトリパスのみが必要で、ここに含まれるファイルの数は気にしない場合は、sort -z | uniq -zc
withsort -zu
またはコマンドをprint
withに置き換えます。print -r $dir
F
答え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
。出力が順番にならない場合。echo
uniq
find
sort
uniq