按照模式对文件名进行分组和计数

Whi*_*hot 3 bash text-processing filenames

我在具有特定命名系统的文件夹中有大量文件。它看起来有点像这样:

my_file_A_a.txt
my_file_A_d.txt
my_file_A_f.txt
my_file_A_t.txt
my_file_B_r.txt
my_file_B_x.txt
my_file_C_f.txt
my_file_D_f.txt
my_file_D_g.txt
my_file_E_r.txt
Run Code Online (Sandbox Code Playgroud)

我想要一个命令行或一系列命令(可以使用临时文件,我有写访问权限),它会返回类似以下内容的内容:

A: 4
B: 2
C: 1
D: 2
E: 1
Run Code Online (Sandbox Code Playgroud)

可以用很多ls -1 *A* | wc -l命令来完成,但是需要很长时间,因为有几百个“组”需要统计。

此外,每个组的名称都是唯一的。有A团体,有B团体,但没有AB团体。

Adm*_*Bee 6

假设您的文件名“行为良好”,即它们不包含换行符,则以下ls和的组合awk将起作用:

ls -d my_file* | awk -F'_' 'NF==4{count[$3]++} END{for (i in count) printf "%s: %d\n", i, count[i]}'
Run Code Online (Sandbox Code Playgroud)

这将重定向列出启动程序ls的所有文件的命令的输出。该程序将使用as 字段分隔符并检查第三个字段来跟踪数组中的出现情况,该数组使用组号作为“数组索引”。my_file*awkawk_count

最后,它会打印每个组发生频率的概述。

注意

  • 通过要求恰好 4 个这样的字段,可以对完全畸形的文件名提供“最低”保护。这假设_不能是示例中文件名的a, d, ,... 部分的一部分。f
  • 输出不一定根据类别名称排序。排序顺序取决于循环awk中数组索引的遍历方式for (i in count)。如果需要排序,您可以向 中添加另一个管道sort。或者,如果您使用 GNU Awk,您可以通过以下方式添加配置设置
    BEGIN{PROCINFO["sorted_in"]="@ind_str_asc"}
    
    Run Code Online (Sandbox Code Playgroud) 规则之前NF==4{...}。这将确保根据数组索引遍历数组,并按字典 (ASCII) 顺序排序。
  • 这将适用于开头所述的限制,并且因为您的文件名结构相当简单。一般来说,不鼓励解析 的输出ls