Bash

按照模式對文件名進行分組和計數

  • September 30, 2021

我在具有特定命名系統的文件夾中有大量文件。它看起來有點像這樣:

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

我想要一個命令行或一系列命令(可以使用臨時文件,我有寫權限),它們會返回如下內容:

A: 4
B: 2
C: 1
D: 2
E: 1

可以用很多ls -1 *A* | wc -l命令來完成,但是需要很長時間,因為要計算幾百個“組”。

此外,每個組名都是唯一的。有一個A群,一個B群,但沒有AB群。

for f in my_file_*_*.txt
do
   f="${f#my_file_}"
   printf "%s\n" "${f%%_*.txt}"
done |
sort |
uniq -c

for循環重新格式化每個文件名以f去除前導my_file_和尾隨_whatever.txt,然後對該輸出進行排序,並用於uniq計算每個唯一值的出現次數。

假設您的文件名是“行為良好的”,即它們不包含換行符,下面的ls和組合awk將起作用:

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

這將重定向ls列出所有開始my_file*awk程序的文件的命令的輸出。該awk程序將使用_as 欄位分隔符並檢查第三個欄位以跟踪數組中的出現count,該數組使用組號作為“數組索引”。

最後,它會列印出每個組發生頻率的概覽。

注意

  • 通過要求恰好 4 個這樣的欄位,可以“最低限度地”保護文件名格式完全錯誤。這假設, , ,… 在您的範例_中不能是文件名的一部分。a``d``f
  • 輸出不一定會根據類別名稱進行排序。排序順序將取決於如何遍歷循環awk中的數組索引。for (i in count)如果需要排序,您可以在sort. 或者,如果您使用 GNU Awk,您可以通過添加配置設置
BEGIN{PROCINFO["sorted_in"]="@ind_str_asc"}

NF==4{...}規則之前。這將確保根據數組索引遍歷數組,按字典(ASCII)順序排序。

  • 這將適用於開頭所述的限制,並且因為您的文件名結構相當簡單。通常不鼓勵解析ls.

引用自:https://unix.stackexchange.com/questions/671134