IT story

하위 디렉터리를 포함한 코드 줄을 계산하는 방법

hot-time 2020. 9. 8. 22:02
반응형

하위 디렉터리를 포함한 코드 줄을 계산하는 방법


프로젝트에서 코드 줄을 세고 싶다고 가정 해 보겠습니다. 모든 파일이 동일한 디렉토리에 있으면 실행할 수 있습니다.

cat * | wc -l

그러나 하위 디렉터리가있는 경우 작동하지 않습니다. 이것이 작동하려면 cat은 재귀 모드를 가져야합니다. 나는 이것이 xargs에 대한 직업이라고 생각하지만 더 우아한 해결책이 있는지 궁금합니다.


먼저 cat줄을 세는 데 사용할 필요가 없습니다 . 이것은 UUoC ( Useless Use of Cat)라는 반 패턴 입니다. 현재 디렉토리에있는 파일의 행을 계산하려면 wc다음을 사용하십시오 .

wc -l * 

그런 다음 find명령은 하위 디렉토리를 반복합니다.

find . -name "*.c" -exec wc -l {} \;
  • . 검색을 시작할 최상위 디렉토리의 이름입니다.

  • -name "*.c" 관심있는 파일의 패턴입니다.

  • -exec 실행할 명령을 제공합니다

  • {}명령에 전달할 find 명령의 결과입니다 (여기 wc-l).

  • \; 명령의 끝을 나타냅니다.

당신이 합이하려는 경우이 명령은, 자신의 라인 카운트에있는 모든 파일의 목록을 생성하는 모든 파일, 당신은합니다 (와 파일 목록을 찾을 수 있습니다 발견 -print인수로이 목록을 전달하는 옵션) 및 사용 xargs를보다가 wc-l에.

find . -name "*.c" -print | xargs wc -l 

EDIT to address Robert Gamble comment (thanks) : 파일 이름에 공백이나 줄 바꿈 (!)이 있으면 파일 이름 목록이 null로 끝나는 문자열로 교환되도록 and -print0대신 옵션 을 사용해야 합니다.-printxargs -null

find . -name "*.c" -print0 | xargs -0 wc -l

유닉스 철학은 한 가지만 수행하고 잘 수행하는 도구를 갖는 것입니다.


코드 골프에 대한 답변을 원한다면 :

grep '' -R . | wc -l 

wc -l을 단독으로 사용하는 문제는 잘 내려갈 수 없으며 oneliners는

find . -exec wc -l {} \;

모든 파일에 대해 wc를 한 번 실행하기 때문에 총 줄 수를 제공하지 않습니다 (loL!) 및

find . -exec wc -l {} + 

find가 매개 변수에 대한 ~ 200k 1 , 2 문자 인수 제한에 도달 하자마자 혼란스러워 지고 대신 wc를 여러호출 하여 매번 부분 요약 만 제공합니다.

또한 위의 grep 트릭은 바이너리 파일을 발견 할 때 출력에 1 줄 이상을 추가하지 않으므로 상황에 따라 도움이 될 수 있습니다.

1 개의 추가 명령 문자 비용으로 바이너리 파일을 완전히 무시할 수 있습니다.

 grep '' -IR . | wc -l

바이너리 파일에서도 줄 수를 실행하려면

 grep '' -aR . | wc -l 
한도에 대한 각주 :

문서는 문자열 크기 제한인지 토큰 수 제한 인지에 대해 약간 모호 합니다.

cd /usr/include;
find -type f -exec perl -e 'printf qq[%s => %s\n], scalar @ARGV, length join q[ ], @ARGV' {} + 
# 4066 => 130974
# 3399 => 130955
# 3155 => 130978
# 2762 => 130991
# 3923 => 130959
# 3642 => 130989
# 4145 => 130993
# 4382 => 130989
# 4406 => 130973
# 4190 => 131000
# 4603 => 130988
# 3060 => 95435

이것은 매우 쉽게 덩어리가된다는 것을 의미합니다.


아마 xargs에 갇힌 것 같아요

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

chromakode 의 방법은 동일한 결과를 제공하지만 훨씬 느립니다. xargs를 사용하면 find 가 찾기를 시작 하자마자 cat ing 및 wc ing을 시작할 수 있습니다 .

Linux 에서의 좋은 설명 : xargs 대 exec {}


find기본적으로 디렉토리를 반복 하는 명령을 사용해보십시오 .

find . -type f -execdir cat {} \; | wc -l


올바른 방법은 다음과 같습니다.

find . -name "*.c" -print0 | xargs -0 cat | wc -l

You must use -print0 because there are only two invalid characters in Unix filenames: The null byte and "/" (slash). So for example "xxx\npasswd" is a valid name. In reality, you're more likely to encounter names with spaces in them, though. The commands above would count each word as a separate file.

You might also want to use "-type f" instead of -name to limit the search to files.


Using cat or grep in the solutions above is wasteful if you can use relatively recent GNU tools, including Bash:

wc -l --files0-from=<(find . -name \*.c -print0)

This handles file names with spaces, arbitrary recursion and any number of matching files, even if they exceed the command line length limit.


I like to use find and head together for "a recursively cat" on all the files in a project directory, for example:

find . -name "*rb" -print0 | xargs -0 head -10000

The advantage is that head will add your the filename and path:

==> ./recipes/default.rb <==
DOWNLOAD_DIR = '/tmp/downloads'
MYSQL_DOWNLOAD_URL = 'http://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.10-debian6.0-x86_64.deb'
MYSQL_DOWNLOAD_FILE = "#{DOWNLOAD_DIR}/mysql-5.6.10-debian6.0-x86_64.deb"

package "mysql-server-5.5"
...

==> ./templates/default/my.cnf.erb <==
#
# The MySQL database server configuration file.
#
...

==> ./templates/default/mysql56.sh.erb <==
PATH=/opt/mysql/server-5.6/bin:$PATH 

For the complete example here, please see my blog post :

http://haildata.net/2013/04/using-cat-recursively-with-nicely-formatted-output-including-headers/

Note I used 'head -10000', clearly if I have files over 10,000 lines this is going to truncate the output ... however I could use head 100000 but for "informal project/directory browsing" this approach works very well for me.


If you want to generate only a total line count and not a line count for each file something like:

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

works well. This saves you the need to do further text filtering in a script.


wc -cl `find . -name "*.php" -type f`

Here's a Bash script that counts the lines of code in a project. It traverses a source tree recursively, and it excludes blank lines and single line comments that use "//".

# $excluded is a regex for paths to exclude from line counting
excluded="spec\|node_modules\|README\|lib\|docs\|csv\|XLS\|json\|png"

countLines(){
  # $total is the total lines of code counted
  total=0
  # -mindepth exclues the current directory (".")
  for file in `find . -mindepth 1 -name "*.*" |grep -v "$excluded"`; do
    # First sed: only count lines of code that are not commented with //
    # Second sed: don't count blank lines
    # $numLines is the lines of code
    numLines=`cat $file | sed '/\/\//d' | sed '/^\s*$/d' | wc -l`
    total=$(($total + $numLines))
    echo "  " $numLines $file
  done
  echo "  " $total in total
}

echo Source code files:
countLines
echo Unit tests:
cd spec
countLines

Here's what the output looks like for my project:

Source code files:
   2 ./buildDocs.sh
   24 ./countLines.sh
   15 ./css/dashboard.css
   53 ./data/un_population/provenance/preprocess.js
   19 ./index.html
   5 ./server/server.js
   2 ./server/startServer.sh
   24 ./SpecRunner.html
   34 ./src/computeLayout.js
   60 ./src/configDiff.js
   18 ./src/dashboardMirror.js
   37 ./src/dashboardScaffold.js
   14 ./src/data.js
   68 ./src/dummyVis.js
   27 ./src/layout.js
   28 ./src/links.js
   5 ./src/main.js
   52 ./src/processActions.js
   86 ./src/timeline.js
   73 ./src/udc.js
   18 ./src/wire.js
   664 in total
Unit tests:
   230 ./ComputeLayoutSpec.js
   134 ./ConfigDiffSpec.js
   134 ./ProcessActionsSpec.js
   84 ./UDCSpec.js
   149 ./WireSpec.js
   731 in total

Enjoy! --Curran


find . -name "*.h" -print | xargs wc -l

참고URL : https://stackoverflow.com/questions/316590/how-to-count-lines-of-code-including-sub-directories

반응형