win10 - windows bash教學




如何遞歸計算目錄中的所有代碼行? (20)

WC -L? 更好地使用GREP -C ^

wc -l? 錯誤! wc命令統計新行代碼, 而不是行! 當文件中的最後一行不以新的行代碼結束時, 這將不會被計算在內!

如果你仍然需要計數行,請使用grep -c ^ ,完整示例:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

最後,注意wc -l陷阱(計數進入,而不是行!)

我們有一個PHP應用程序,並且想要統計特定目錄及其子目錄下的所有代碼行。 我們不需要忽視評論,因為我們只是想弄清楚一個概念。

wc -l *.php 

該命令在給定的目錄中工作良好,但忽略子目錄。 我認為這可能會起作用,但它正在返回74,這絕對不是這種情況...

find . -name '*.php' | wc -l

在所有文件中輸入正確的語法是什麼?


POSIX

每個文件中的行:

find . -name '*.php' -type f | xargs wc -l

每個文件中的行,按文件路徑排序

find . -name '*.php' -type f | sort | xargs wc -l

每個文件中的行按行數排序,遞減

find . -name '*.php' -type f | xargs wc -l | sort -nr

所有文件中的總行數

find . -name '*.php' -type f | xargs cat | wc -l

一個簡單的快速的將會使用find所有搜索/過濾功能,當文件太多(數字參數溢出)時,不會失敗,對於名稱中帶有滑稽符號的文件可以正常工作,不使用xargs ,不會啟動一個無用的高數量的外部命令(感謝+ for find-exec )。 幹得好:

find . -name '*.php' -type f -exec cat -- {} + | wc -l

令人驚訝的是,基於find的-execawk沒有答案。 開始了:

find . -type f -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }'

這段代碼找到所有文件( -type f )。 要通過文件擴展名查找,請使用-name

find . -name *.py -exec wc -l {} \; | awk '{ SUM += $0} END { print SUM }'

你想要的是一個簡單的for循環:

total_count=0
for file in $(find . -name *.php -print)
do
count=$(wc -l $file)
let total_count+=count
done
echo $total_count

僅用於來源:

wc `find`

要過濾,只需使用grep

wc `find | grep .php$`

另一個命令是獲得所有文件的總和(當然是Linux)

find ./ -type f -exec wc -l {}  \; | cut -d' ' -f1 | paste -sd+ | bc

與其他答案的主要區別:

  1. 使用find -exec
  2. 使用粘貼(與切割)
  3. 使用bc

在類UNIX系統上,有一個名為cloc的工具,它提供了代碼統計信息。

我跑到我們的代碼庫中的一個隨機目錄中,它說:

      59 text files.
      56 unique files.                              
       5 files ignored.

http://cloc.sourceforge.net v 1.53  T=0.5 s (108.0 files/s, 50180.0 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C                               36           3060           1431          16359
C/C++ Header                    16            689            393           3032
make                             1             17              9             54
Teamcenter def                   1             10              0             36
-------------------------------------------------------------------------------
SUM:                            54           3776           1833          19481
-------------------------------------------------------------------------------

如果使用Bash(或ZSH)的新版本,它更簡單:

wc -l **/*.php

在Bash shell中,這需要設置globstar選項,否則** glob-operator不是遞歸的。 要啟用此設置,請發出

shopt -s globstar

為了使其成為永久的,將它添加到其中一個初始化文件( ~/.bashrc~/.bash_profile等)。


如果您只需要總數的行數,讓我們說您的PHP文件,即使在Windows下,如果您安裝了GnuWin32,也可以使用非常簡單的一行命令。 喜歡這個:

cat `/gnuwin32/bin/find.exe . -name *.php` | wc -l

您需要指定find.exe的確切位置,否則將執行Windows提供的FIND.EXE(來自舊DOS類命令),因為它可能位於環境PATH中的GnuWin32之前,並且具有不同的參數和結果。

請注意,在上面的命令中,你應該使用反引號,而不是單引號。


對於另一個單線:

( find ./ -name '*.php' -print0 | xargs -0 cat ) | wc -l

使用空格名稱,只輸出一個數字。


對於我來說更普遍和簡單,假設你需要計算不同名稱擴展名的文件(比如說也是本機)

wc `find . -name '*.[h|c|cpp|php|cc]'`

您沒有指定有多少個文件或什麼是所需的輸出。 這是你想要的:

find . -name '*.php' | xargs wc -l

我使用了從src-project目錄啟動的這個內聯腳本:

 for i in $(find . -type f); do rowline=$(wc -l $i | cut -f1 -d" "); file=$(wc -l $i | cut -f2 -d" "); lines=$((lines + rowline)); echo "Lines["$lines"] " $file "has "$rowline"rows."; done && unset lines

這產生了這個輸出:

Lines[75]  ./Db.h has 75rows.
Lines[143]  ./Db.cpp has 68rows.
Lines[170]  ./main.cpp has 27rows.
Lines[294]  ./Sqlite.cpp has 124rows.
Lines[349]  ./Sqlite.h has 55rows.
Lines[445]  ./Table.cpp has 96rows.
Lines[480]  ./DbError.cpp has 35rows.
Lines[521]  ./DbError.h has 41rows.
Lines[627]  ./QueryResult.cpp has 106rows.
Lines[717]  ./QueryResult.h has 90rows.
Lines[828]  ./Table.h has 111rows.

我知道這個問題被標記為bash ,但似乎你想解決的問題也是PHP相關的。

塞巴斯蒂安貝格曼寫​​了一個名為PHPLOC的工具,它可以完成你想要的任務,並且為你提供項目複雜性的概述。 這是其報告的一個例子:

Size
  Lines of Code (LOC)                            29047
  Comment Lines of Code (CLOC)                   14022 (48.27%)
  Non-Comment Lines of Code (NCLOC)              15025 (51.73%)
  Logical Lines of Code (LLOC)                    3484 (11.99%)
    Classes                                       3314 (95.12%)
      Average Class Length                          29
      Average Method Length                          4
    Functions                                      153 (4.39%)
      Average Function Length                        1
    Not in classes or functions                     17 (0.49%)

Complexity
  Cyclomatic Complexity / LLOC                    0.51
  Cyclomatic Complexity / Number of Methods       3.37

正如您所看到的,從開發人員的角度來看,所提供的信息更加有用,因為它可以粗略地告訴您在開始使用它之前項目有多複雜。


有一個名為sloccount的小工具來計算目錄中的代碼行。 應該注意的是,它比你想要的要多,因為它忽略空行/註釋,按照編程語言對結果進行分組,併計算一些統計數據。


猜測沒有人會看到它埋在後面......但迄今沒有任何答案可以解決帶空格的文件名問題。 另外,如果樹中路徑的總長度超過shell環境大小限制(在Linux中默認為幾兆字節),那麼所有使用xargs的應用程序都會失敗。 這是一個以相當直接的方式解決這些問題的方法。 subshel​​l使用空格來處理文件。 awk總結了單個文件wc輸出的流,所以不應該耗盡空間。 它還將exec限制為僅文件(跳過目錄):

find . -type f -name '*.php' -exec bash -c 'wc -l "$0"' {} \; | awk '{s+=$1} END {print s}' 

至少在OS X上,某些其他答案中列出的find + xarg + wc命令會在大型列表中多次打印“總計”,並且沒有給出完整的總計。 我可以使用以下命令獲得一個.c文件的總數:

find . -name '*.c' -print0 |xargs -0 wc -l|grep -v total|awk '{ sum += $1; } END { print "SUM: " sum; }'


非常簡單

find /path -type f -name "*.php" | while read FILE
do
    count=$(wc -l < $FILE)
    echo "$FILE has $count lines"
done

首先給出最長的文件(也許這些長文件需要一些重構愛),並排除一些供應商目錄:

 find . -name '*.php' | xargs wc -l | sort -nr | egrep -v "libs|tmp|tests|vendor" | less




shell