windows - tag - ¿Cómo contar el número de líneas en el archivo de texto y almacenar el valor en una variable usando el script por lotes?
tag folders (13)
Quiero contar el número de líneas en un archivo de texto y luego el valor debe almacenarse en una variable de entorno. El comando para contar el no de líneas es
findstr /R /N "^" file.txt | find /C ":"
Remití la pregunta ¿Cómo almacenar el resultado de una expresión de comando en una variable usando scripts bat? Entonces lo intenté,
set cmd="findstr /R /N "^" file.txt | find /C ":" "
Recibo el mensaje de error,
FIND: Parameter format not correct
¿Cómo podría deshacerme de este error?
@ Tony: incluso puedes deshacerte del comando type %file%
.
for /f "tokens=2 delims=:" %%a in (''find /c /v "" %_file%'') do set /a _Lines=%%a
Para archivos largos, esto debería ser aún más rápido.
En el siguiente código, el nombre de la variable es SalaryCount
y TaxCount
@ECHO OFF
echo Process started, please wait...
for /f %%C in (''Find /V /C "" ^< "D:/Trial/Salary.txt"'') do set SalaryCount=%%C
echo Salary,%SalaryCount%
for /f %%C in (''Find /V /C "" ^< "D:/Trial/Tax.txt"'') do set TaxCount=%%C
echo Tax,%TaxCount%
Ahora, si necesita generar estos valores en un archivo csv, puede usar el siguiente código.
@ECHO OFF
cd "D:/CSVOutputPath/"
echo Process started, please wait...
echo FILENAME,FILECOUNT> SUMMARY.csv
for /f %%C in (''Find /V /C "" ^< "D:/Trial/Salary.txt"'') do set Count=%%C
echo Salary,%Count%>> SUMMARY.csv
for /f %%C in (''Find /V /C "" ^< "D:/Trial/Tax.txt"'') do set Count=%%C
echo Tax,%Count%>> SUMMARY.csv
El >
sobrescribirá el contenido existente del archivo y >>
agregará los datos nuevos a los datos existentes. El CSV se generará en D: / CSVOutputPath
Encontré que esta solución funciona mejor para crear un archivo de registro que se mantenga solo:
setlocal enabledelayedexpansion
SET /A maxlines= 10
set "cmd=findstr /R /N "^^" "filename.txt" | find /C ":""
for /f %%a in (''!cmd!'') do set linecount=%%a
GOTO NEXT
:NEXT
FOR /F %%A IN ("filename.txt") DO (
IF %linecount% GEQ %maxlines% GOTO ExitLoop
echo %clientname% %Date% %Time% >> "filename.txt")
EXIT
:ExitLoop
echo %clientname% %Date% %Time% > "filename.txt"
EXIT
Las variables ambientales incluidas son% clientname% the computername del cliente remoto% Date% es la fecha actual y% Time% la hora actual. : NEXT se invoca después de obtener el número de líneas en el archivo. Si el recuento de líneas de archivos es mayor que la variable% maxlines% va a: EXITLOOP donde sobrescribe el archivo, creando uno nuevo con la primera línea de información. si es menor que la variable% maxlines%, simplemente agrega la línea al archivo actual.
Hay una manera mucho más simple que todos estos otros métodos.
find /v /c "" filename.ext
Remanente de los días heredados de MS-DOS, al parecer. Más información aquí: http://blogs.msdn.com/b/oldnewthing/archive/2011/08/25/10200026.aspx
Ejemplo de uso:
adb shell pm list packages | find /v /c ""
Si su dispositivo Android está conectado a su PC y tiene el SDK de Android en su ruta, imprime la cantidad de aplicaciones instaladas en su dispositivo.
Inspirado por las publicaciones anteriores, una manera más corta de hacerlo:
CMD.exe
C:/>FINDSTR /R /N "^.*$" file.txt | FIND /C ":"
El número de líneas
Intentalo. Funciona en mi consola.
EDITADO:
(el signo "$" eliminado)
FINDSTR /R /N "^.*" file.txt | FIND /C ":"
$ reduce el número en 1 porque acepta la primera fila como Nombre del campo y luego cuenta el número de filas.
La :countLines
subrutina :countLines
acepta dos parámetros: un nombre de variable; y un nombre de archivo. Se cuenta el número de líneas en el archivo, el resultado se almacena en la variable y el resultado se devuelve al programa principal.
El código tiene las siguientes características:
- Lee archivos con terminaciones de línea de Windows o Unix.
- Maneja Unicode así como archivos de texto ANSI / ASCII.
- Se adapta a líneas extremadamente largas.
- No está confundido por el carácter nulo.
- Se produce un error al leer un archivo vacío.
- Cuenta más allá del límite máximo máximo de lotes de
(31^2)-1
.
@echo off & setLocal enableExtensions disableDelayedExpansion
call :countLines noOfLines "%~1" || (
>&2 echo(file "%~nx1" is empty & goto end
) %= cond exec =%
echo(file "%~nx1" has %noOfLines% line(s)
:end - exit program with appropriate errorLevel
endLocal & goto :EOF
:countLines result= "%file%"
:: counts the number of lines in a file
setLocal disableDelayedExpansion
(set "lc=0" & call)
for /f "delims=:" %%N in (''
cmd /d /a /c type "%~2" ^^^& ^<nul set /p "=#" ^| (^
2^>nul findStr /n "^" ^&^& echo(^) ^| ^
findStr /blv 1: ^| 2^>nul findStr /lnxc:" "
'') do (set "lc=%%N" & call;) %= for /f =%
endlocal & set "%1=%lc%"
exit /b %errorLevel% %= countLines =%
Sé que se ve horrible, pero cubre la mayoría de los casos extremos y es sorprendentemente rápido.
No necesita usar find.
@echo off
set /a counter=0
for /f %%a in (filename) do set /a counter+=1
echo Number of lines: %counter%
Esto itera todas las líneas en el archivo y aumenta la variable del contador en 1 para cada línea.
Prueba esto:
@Echo off
Set _File=file.txt
Set /a _Lines=0
For /f %%j in (''Find "" /v /c ^< %_File%'') Do Set /a _Lines=%%j
Echo %_File% has %_Lines% lines.
Elimina el FindStr adicional y no necesita expansión.
- editado para usar la sugerencia de redirección de ChrisJJ. La eliminación del comando TYPE
hace tres veces más rápido.
Puede canalizar la salida de type
en find
dentro de la cláusula in(…)
de un bucle for /f
:
for /f %%A in (''
type "%~dpf1" ^| find /c /v ""
'') do set "lineCount=%%A"
Pero la tubería comienza una subcapa, lo que ralentiza las cosas.
O bien, puede redireccionar la entrada del archivo para find
manera:
for /f %%A in (''
find /c /v "" ^< "%~dpf1"
'') do set "lineCount=%%A"
Pero este enfoque le dará una respuesta 1 menos que el número real de líneas si el archivo termina con una o más líneas en blanco, como lo hizo el último foxidrive en líneas de conteo en un archivo .
Y, nuevamente, siempre puedes intentar:
find /c /v "" example.txt
El problema es que el resultado del comando anterior se ve así:
---------- EXAMPLE.TXT: 511
Podría dividir la cadena en los dos puntos para obtener el conteo, pero podría haber más de un punto si el nombre del archivo tuviera una ruta completa.
Aquí está mi opinión sobre ese problema:
for /f "delims=" %%A in (''
find /c /v "" "%~1"
'') do for %%B in (%%A) do set "lineCount=%%B"
Esto siempre almacenará el conteo en la variable.
Solo un último pequeño problema ... find
trata los caracteres nulos como líneas nuevas. Por lo tanto, si los nulos furtivos ingresan en su archivo de texto, o si desea contar las líneas en un archivo Unicode, esta respuesta no es para usted.
Puede usar el ciclo FOR / F para asignar la salida a una variable.
Utilizo la cmd-variable
, por lo que no es necesario escapar de la tubería u otros caracteres en la cadena cmd, ya que la expansión retrasada pasa la cadena "sin cambios" al FOR-Loop.
@echo off
cls
setlocal EnableDelayedExpansion
set "cmd=findstr /R /N "^^" file.txt | find /C ":""
for /f %%a in (''!cmd!'') do set number=%%a
echo %number%
Sólo:
c:/>(for /r %f in (*.java) do @type %f ) | find /c /v ""
Fuente: https://superuser.com/questions/959036/what-is-the-windows-equivalent-of-wc-l
Usualmente uso algo más como este for /f %%a in (%_file%) do (set /a Lines+=1)
for /f "usebackq" %A in (`TYPE c:/temp/file.txt ^| find /v /c "" `) do set numlines=%A
en un archivo por lotes, use %% A en lugar de% A