列出并计算字符串中具有相同名称字符的文件的子目录

列出并计算字符串中具有相同名称字符的文件的子目录

想象一下这个:

 |-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_1E_2

使用匿名函数缩短:

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

如果您只需要目录路径而不关心它包含多少个文件,请将sort -z | uniq -zcwithsort -zu或命令替换print为。print -r $dirF

答案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输出不按顺序排列,您可能需要sortuniq.

相关内容