想象一下这个:
|-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
我有这样的子目录结构,其中包含具有特定名称的文件。我需要帮助确定哪些子目录以及多少个名为“E_NUMBER”的子目录在其子目录中包含带有字符“F”的文件,例如 Unix 或 Python 中的字符“F”。
任何帮助将受到欢迎。谢谢!
答案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
为。print -r $dir
F
答案2
我不确定你所说的“在 Unix 中”是什么意思。如果最近的 shell 可以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_NUMBER”转换为正则表达式E_[[:digit:]]
)中,相应的文件名包含F
,则它echo
是命令要计数的路径名uniq
。如果find
输出不按顺序排列,您可能需要sort
在uniq
.