![列出并计算字符串中具有相同名称字符的文件的子目录](https://linux22.com/image/212578/%E5%88%97%E5%87%BA%E5%B9%B6%E8%AE%A1%E7%AE%97%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E5%85%B7%E6%9C%89%E7%9B%B8%E5%90%8C%E5%90%8D%E7%A7%B0%E5%AD%97%E7%AC%A6%E7%9A%84%E6%96%87%E4%BB%B6%E7%9A%84%E5%AD%90%E7%9B%AE%E5%BD%95.png)
想象一下这个:
|-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
.