web-dev-qa-db-fra.com

Comment ne compter aucun nombre de lignes dans un fichier texte et stocker la valeur dans une variable en utilisant un script batch?

Je veux compter le nombre de lignes dans un fichier texte, puis la valeur doit être stockée dans une variable d'environnement. La commande pour compter le nombre de lignes est

 findstr/R/N "^" fichier.txt | find/C ":" 

J'ai référé à la question Comment stocker le résultat d'une expression de commande dans une variable à l'aide de scripts bat? Puis j'ai essayé,

 set cmd = "findstr/R/N" ^ "fichier.txt | find/C": "" 

Je reçois le message d'erreur,

 FIND: Le format du paramètre n'est pas correct 

Comment pourrais-je me débarrasser de cette erreur. 

45
rashok

Vous pouvez utiliser la boucle FOR/F pour affecter le résultat à une variable. 

J'utilise le cmd-variable; il n'est donc pas nécessaire d'échapper au tube ou aux autres caractères de la chaîne de commande cmd, car l'extension retardée transmet la chaîne "inchangée" à la boucle FOR.

@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%
33
jeb

Il existe un moyen beaucoup plus simple que toutes ces autres méthodes.

find /v /c "" filename.ext

Les retombées des anciens jours MS-DOS, apparemment. Plus d'informations ici: http://blogs.msdn.com/b/oldnewthing/archive/2011/08/25/10200026.aspx

Exemple d'utilisation:

adb Shell pm list packages | find /v /c ""

Si votre appareil Android est connecté à votre PC et que vous avez le SDK Android sur votre chemin, cela affiche le nombre d'applications installées sur votre appareil.

84
user169771

Inspiré par les messages précédents, Une façon plus rapide de le faire:

CMD.exe
C:\>FINDSTR /R /N "^.*$" file.txt | FIND /C ":"

Le nombre de lignes

Essayez-le Cela fonctionne dans ma console.

ÉDITÉ:

(le signe "$" est supprimé)

FINDSTR /R /N "^.*" file.txt | FIND /C ":"

$ réduit le nombre de 1 car il accepte la première ligne en tant que Nom du champ, puis compte le nombre de lignes.

16
Tin Amaranth

Essaye ça:

@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.

Il élimine le FindStr supplémentaire et ne nécessite pas d'extension.


- édité pour utiliser la suggestion de redirection de ChrisJJ. La suppression de la commande TYPE le rend trois fois plus rapide.

8
Tony

@ Tony: Vous pouvez même vous débarrasser de la commande type %file%.

for /f "tokens=2 delims=:" %%a in ('find /c /v "" %_file%') do set /a _Lines=%%a

Pour les longs fichiers, cela devrait être encore plus rapide.

4
Dazzam

Vous n'avez pas besoin d'utiliser find.

@echo off
set /a counter=0
for /f %%a in (filename) do set /a counter+=1
echo Number of lines: %counter%

Cela itère toutes les lignes du fichier et augmente la variable de compteur de 1 pour chaque ligne.

3
Andreas Mångs
 pour/f "usebackq"% A dans (`TYPE c:\temp\fichier.txt ^ | find/v/c" "`) définir numlines =% A

dans un fichier de commandes, utilisez %% A au lieu de% A

2
Tom Warfield

J'ai trouvé cette solution plus efficace pour créer un fichier journal qui se maintient lui-même:

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

Les variables d'environnement incluses sont% clientname% le nom de l'ordinateur du client distant% Date% est la date actuelle et% heure% l'heure actuelle. : NEXT est appelé après avoir obtenu le nombre de lignes du fichier. Si le nombre de lignes de fichier est supérieur à la variable% maxlines%, il est renvoyé à: EXITLOOP où il écrase le fichier et en crée un nouveau avec la première ligne d'informations. si elle est inférieure à la variable% maxlines%, elle ajoute simplement la ligne au fichier actuel. 

2
joopykunk

Juste:

c:\>(for /r %f in (*.Java) do @type %f ) | find /c /v ""

Police: https://superuser.com/questions/959036/what-is-the-windows-equivalent-of-wc-l

1
Carlos.Cândido

Vous pouvez diriger la sortie de type dans find à l'intérieur de la clause in(…) d'une boucle for /f:

for /f %%A in ('
    type "%~dpf1" ^| find /c /v ""
') do set "lineCount=%%A"

Mais le tuyau commence une sous-coque, ce qui ralentit les choses.

Ou, vous pouvez rediriger les entrées du fichier dans find comme ceci:

for /f %%A in ('
    find /c /v "" ^< "%~dpf1"
') do set "lineCount=%%A"

Mais cette approche vous donnera une réponse inférieure de 1 au nombre réel de lignes si le fichier se termine par une ou plusieurs lignes vides, comme indiqué par la fin du fichier foxidrive in comptant les lignes dans un fichier .

Et puis, vous pouvez toujours essayer:

find /c /v "" example.txt

Le problème, c'est que le résultat de la commande ci-dessus ressemble à ceci:

---------- EXAMPLE.TXT: 511

Vous pouvez diviser la chaîne sur les deux points pour obtenir le nombre, mais il peut y avoir plus de deux points si le nom du fichier contient un chemin complet.

Voici mon point de vue sur ce problème:

for /f "delims=" %%A in ('
    find /c /v "" "%~1"
') do for %%B in (%%A) do set "lineCount=%%B"

Cela enregistrera toujours le nombre dans la variable.

Un dernier petit problème… find traite les caractères nuls comme des retours à la ligne. Ainsi, si des valeurs NULL sournoises s’infiltrent dans votre fichier texte ou si vous souhaitez compter les lignes d’un fichier Unicode, cette réponse n’est pas faite pour vous.

0
Sponge Belly

Dans le code ci-dessous, les noms de variable sont SalaryCount et 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%

Maintenant, si vous devez sortir ces valeurs dans un fichier csv, vous pouvez utiliser le code ci-dessous.

@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

Le > écrase le contenu existant du fichier et le >> ajoute les nouvelles données aux données existantes. Le fichier CSV sera généré dans D:\CSVOutputPath

0
Sarath Avanavu

Le sous-programme :countLines ci-dessous accepte deux paramètres: un nom de variable; et un nom de fichier. Le nombre de lignes du fichier est compté, le résultat est stocké dans la variable et le résultat est renvoyé au programme principal.

Le code présente les caractéristiques suivantes:

  • Lit les fichiers avec des fins de ligne Windows ou Unix.
  • Gère les fichiers Unicode et ANSI/ASCII.
  • Faire face à des lignes extrêmement longues.
  • N’est pas dérouté par le caractère nul.
  • Déclenche une erreur lors de la lecture d'un fichier vide.
  • Compte au-delà de la limite maximale de lot par (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 =%

Je sais que cela semble hideux, mais il couvre la plupart des cas Edge et est étonnamment rapide.

0
Sponge Belly