Programming w/ C# ~ ステップカウンタ

C# ソースの (フォルダ再帰的な) ステップカウンタ

ソースコードのファイル数・行数を簡便に知りたい。
dir /b /s から find /v /c へ繋いでワンライナー的にやれば ... といつも思って検索をかけるものの、なかなかズバリの解が出てこないため、バッチファイルでステップカウンタを自作した。

@echo off

setlocal enabledelayedexpansion

for /f "usebackq delims=" %%f in (`dir *.cs /b /s ^| findstr /v "\obj"`) do (
  for /f "usebackq delims=" %%c in (`type %%f ^| find /v /c ""`) do (
    set /a LINES+=%%c
    set /a FILES+=1
    set COUNT=     %%c

    echo !COUNT:~-5! %%f
  )
)

set LINES=     !LINES!
echo ---------------------------------------------------------------------------
echo !LINES:~-5! line(s) in !FILES! file(s).

endlocal

dir /b /s コマンドで .cs ファイルの名称をフォルダ再帰で取得し、findstr /v コマンドで \obj フォルダ格納分を対象から除く。
ファイルを1つ1つ find /v /c へ喰わせて行数カウントし LINES 変数へ加算、同時にFILES 変数でファイル数をカウントする。
あとは各ファイルの行数をファイル名、総計を左空白パディングして出力。

実質は 1 重ループであるにも関わらず、コマンド実行結果を変数に割り当てるための 2 つ目の for 文がちょっとイケていない。

C# ソースの (フォルダ再帰的な) 正規表現マッチング

もう一つおまけに、ファイル再帰的に正規表現マッチングするバッチファイルも作ってみた。(文字/改行コード = UTF8/LF 用)

@echo off

setlocal enabledelayedexpansion

set FCNTSUM=0
set LCNTSUM=0
rem DO NOT TRIM BLANK LINES, because the following THREE lines define a variable for an LF character
set LF=^



cls
chcp 65001 >nul

for /f "usebackq delims=" %%f in (`dir *.cs /b /s ^| findstr /v "\obj"`) do (
  set LCNT0=0
  set CONTENT=

  for /f "usebackq delims=" %%c in (`type %%f ^| findstr /n /r /c:%1 %2 %3 %4 %5 %6 %7 %8 %9`) do (
    set /a LCNT0+=1
    set CONTENT=!CONTENT!%%c
    set CONTENT=!CONTENT!!LF!
  )

  if not "!LCNT0!"=="0" (
    set /a FCNTSUM+=1
    set /a LCNTSUM+=!LCNT0!
    set LCNT1=     !LCNT0!
    set LCNT2=!LCNT1:~-5!
    set HEADER=[!LCNT2!][%%f] ------------------------------------------------------------------------------------------

    echo !HEADER:~0,116!
    echo !CONTENT!
    echo.
  )
)

echo ===================================================================================================================
echo !LCNTSUM! line(s) hit in !FCNTSUM! file(s).

endlocal

!CONTENT!%%c!LF! とを結合するのを 2 回に分けるのは %%c の文字列内容に ! が入ると、対象文字列とコンテクストと混同して ! の認識が逆転し、バグり程度がひどくなる (コンテクスト中の !LF!LF が文字列に埋め込まれてしまう) から。

文字列中の !^! へ置換すればよい*1、変数中の文字列置換はこう*2すればよいとのことだが、! のような特殊文字バッチ処理では置換できないようだ。文字列とコンテクストの区別がつかないし、文字列の変換もできないとはなんと出来の悪い言語仕様だ。

バッチファイル書くのしんどい ... 動的型付け言語は好きじゃない。