統計專案代碼行數是常見需求。本文提供兩種 Linux 下實現:Shell 腳本版(簡潔強大,支援按後綴過濾、顏色輸出)與 C 語言版(系統編程實踐,遞歸遍歷目錄、fgets 逐行統計),並附完整代碼與運行截圖說明。
find $1 -maxdepth $2 -name "$3" 檢索目標文件。wc -l 統計每文件行數,輸出格式 行數 文件名。awk '{print $1}' 提取行數字段,累加總計。# 參數:$1=路徑 $2=最大深度 $3=文件後綴正則
for file in $(find "$1" -maxdepth "$2" -name "$3"); do
t=$(wc -l < "$file") # 只取行數,不含文件名
echo -e "$file: \e[1;32m $t \e[0m"
w=$((w + t))
done
echo -e "\e[1;31m total: \e[1;32m $w \e[0m"
*.c、*.h)。opendir/readdir/closedir(dirent.h)遍歷目錄。chdir(unistd.h)切換工作目錄實現遞歸。lstat + S_ISDIR(sys/stat.h)判斷文件類型。fgets 逐行讀取統計。#include#include #include #include #include #include #include #include #define MAXLINE 200 int linecount = 0; int getLine(char *fname) { FILE *fp = fopen(fname, "r"); char line[MAXLINE]; int total = 0; while (fgets(line, MAXLINE, fp) != NULL) total++; fclose(fp); return total; } void Recur_dir(const char *dir, int depth) { DIR *dp; struct dirent *entry; struct stat statbuf; if ((dp = opendir(dir)) == NULL) { perror("opendir"); exit(1); } chdir(dir); while ((entry = readdir(dp)) != NULL) { lstat(entry->d_name, &statbuf); if (S_ISDIR(statbuf.st_mode)) { if (strcmp(".", entry->d_name)==0 || strcmp("..", entry->d_name)==0) continue; Recur_dir(entry->d_name, depth+4); } else { linecount += getLine(entry->d_name); } } chdir(".."); closedir(dp); } int main(int argc, char *argv[]) { char *topdir = "."; if (argc > 2) { fprintf(stderr, "Usage: %s [dir]\n", argv[0]); exit(1); } if (argc == 2) topdir = argv[1]; Recur_dir(topdir, 0); printf("Total: %d\n", linecount); return 0; }
. 和 .. 避免死循環。chdir("..") 返回上層。| 維度 | Shell 版 | C 版 |
|---|---|---|
| 代碼量 | ~20 行 | ~80 行 |
| 靈活性 | 高(管道組合) | 需手工擴展 |
| 性能 | 進程開銷大 | 單進程、較快 |
| 移植性 | 依賴 GNU 工具 | 標準 C,易移植 |