Bash
按照模式對文件名進行分組和計數
我在具有特定命名系統的文件夾中有大量文件。它看起來有點像這樣:
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
.