使用批处理文件计算行数和列数

Count rows and columns using a batch file

我需要计算几个文件的行数和列数。到目前为止,我设法获得了行数

@echo off
if exist counts.txt del counts.txt
for /R "path To folder" %%a in (*.txt) do call :sub %%a
goto :eof

:Sub
for /F %%c in ('type "%*" ^| find /c /v ""') do set rowCount=%%c
echo %*;%rowCount% >> counts.txt

此批处理文件保存文件名和行数,以 ; 分隔。我遇到的问题是列数。有什么想法吗?

可能输出会是

file path;row count;col count

解决方案 1:

一个基本的 for 循环计算不带引号的逗号、空格、制表符和分号作为分隔符。神奇之处在于它会正确地跳过引号引号。要计算 CSV 文件中的列数,您可以 for %%I in (first line) do increment counter这仅在您的 csv header 行不包含未引号的空格或其他分隔符时才有效。如果您更愿意遵循原始逻辑并计算逗号的数量,请参阅解决方案#2 下面。

@echo off
setlocal

if exist counts.txt del counts.txt
for /R "path To folder" %%a in (*.txt) do call :sub "%%~fa"
goto :eof

:Sub
setlocal
for /F %%c in ('type "%~1" ^| find /c /v ""') do set rowCount=%%c

:: read first line of file.txt into var
set /P "line=" <"%~1"

:: delayed expansion prevents evaluation of special characters
setlocal enabledelayedexpansion
set count=0
for %%I in (!line!) do set /a count += 1
endlocal & set "colCount=%count%"

:: If you want to echo only filename.ext to counts.txt, un-rem this and
:: use %filename% instead of %~1 in your echo. 
rem for %%I in ("%~1") do set "filename=%%~nxI"

echo %~1;%rowCount%;%colCount% >> counts.txt
endlocal

解决方案 2:

用一个:length函数得到header行带逗号和不带逗号的长度,returns差值+1。(:length函数逻辑是基于 jeb's :StringLength。) 这仅在您的 csv 文件没有 header 行,或者如果 header 行保证不包含引号逗号时才有效。

@echo off
setlocal

if exist counts.txt del counts.txt
for /R "path To folder" %%a in (*.txt) do call :sub "%%~fa"
goto :eof

:Sub
setlocal
for /F %%c in ('type "%~1" ^| find /c /v ""') do set rowCount=%%c

:: read first line of file.txt into var
set /P "line=" <"%~1"
set colCount=0

:: delayed expansion prevents evaluation of special characters
setlocal enabledelayedexpansion
set line=!line:"=!
call :length b4 "!line!"
call :length after "!line:,=!"
endlocal & set /a colCount = %b4% - %after% + 1

:: If you want to echo only filename.ext to counts.txt, un-rem this and
:: use %filename% instead of %~1 in your echo.  
rem for %%I in ("%~1") do set "filename=%%~nxI"

echo %~1;%rowCount%;%colCount% >> counts.txt
echo %~1;%rowCount%;%colCount%
endlocal
goto :EOF

:length <return_var> <string>
setlocal enabledelayedexpansion
set "tmpstr=%~2"
set ret=0
for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if not "!tmpstr:~%%I,1!"=="" (
        set /a "ret += %%I"
        set "tmpstr=!tmpstr:~%%I!"
    )
)
endlocal & set "%~1=%ret%"
goto :EOF