Ich möchte die Zeilenanzahl in einer Textdatei zählen und dann muss der Wert in einer Umgebungsvariablen gespeichert werden. Der Befehl, die Anzahl der Zeilen zu zählen, lautet
findstr/R/N "^" file.txt | find/C ":"
Ich verwies auf die Frage Wie kann ich das Ergebnis eines Befehlsausdrucks mithilfe von bat-Skripts in einer Variablen speichern? Dann habe ich versucht,
set cmd = "findstr/R/N" ^ "file.txt | find/C": ""
Ich erhalte die Fehlermeldung,
FIND: Parameterformat nicht korrekt
Wie könnte ich diesen Fehler beseitigen?
Sie können die FOR/F-Schleife verwenden, um die Ausgabe einer Variablen zuzuweisen.
Ich benutze den cmd-variable
, es ist also nicht notwendig, die Pipe oder andere Zeichen in der cmd-Zeichenfolge zu umgehen, da die verzögerte Erweiterung die Zeichenfolge "unverändert" an die FOR-Schleife übergibt.
@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%
Es gibt einen viel einfacheren Weg als alle anderen Methoden.
find /v /c "" filename.ext
Offensichtlich von den alten MS-DOS-Tagen. Weitere Informationen hier: http://blogs.msdn.com/b/oldnewthing/archive/2011/08/25/10200026.aspx
Anwendungsbeispiel:
adb Shell pm list packages | find /v /c ""
Wenn Ihr Android-Gerät mit Ihrem PC verbunden ist und sich das Android SDK im Pfad befindet, wird die Anzahl der auf Ihrem Gerät installierten Apps ausgedruckt.
Inspiriert von den vorherigen Beiträgen, ist .__ ein kürzerer Weg, dies zu tun:
CMD.exe
C:\>FINDSTR /R /N "^.*$" file.txt | FIND /C ":"
Die Anzahl der Zeilen
Versuch es. Es funktioniert in meiner Konsole.
(das "$" Zeichen wurde entfernt)
FINDSTR /R /N "^.*" file.txt | FIND /C ":"
$ reduziert die Anzahl um 1, da die erste Zeile als Feldname akzeptiert und dann die Anzahl der Zeilen gezählt wird.
Versuche dies:
@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.
Es entfällt das zusätzliche FindStr und muss nicht erweitert werden.
- bearbeitet, um den Weiterleitungsvorschlag von ChrisJJ zu verwenden. Durch das Entfernen des Befehls TYPE
wird es dreimal schneller.
Normalerweise benutze ich etwas ähnliches for /f %%a in (%_file%) do (set /a Lines+=1)
@ Tony: Sie können sogar den Befehl type %file%
loswerden.
for /f "tokens=2 delims=:" %%a in ('find /c /v "" %_file%') do set /a _Lines=%%a
Bei langen Dateien sollte dies noch schneller sein.
Sie müssen nicht find verwenden.
@echo off
set /a counter=0
for /f %%a in (filename) do set /a counter+=1
echo Number of lines: %counter%
Dadurch werden alle Zeilen in der Datei durchlaufen und die Zählervariable für jede Zeile um 1 erhöht.
für/f "usebackq"% A in (`TYPE c:\temp\file.txt ^ | find/v/c" ")) setze numlines =% A
verwenden Sie in einer Batchdatei %% A anstelle von% A
Ich fand diese Lösung am besten zum Erstellen einer Protokolldatei, die sich selbst verwaltet:
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
Umgebungsvariablen sind% clientname% der Computername des Remote-Clients.% Date% ist das aktuelle Datum und% Time% die aktuelle Uhrzeit. : NEXT wird aufgerufen, nachdem die Anzahl der Zeilen in der Datei abgerufen wurde. Wenn die Anzahl der Dateizeilen größer als die Variable% maxlines% ist, wird zu: EXITLOOP weitergeleitet, wo die Datei überschrieben wird, wobei eine neue Zeile mit der ersten Informationszeile erstellt wird. Wenn es weniger als die Variable% maxlines% ist, wird die Zeile einfach zur aktuellen Datei hinzugefügt.
Gerade:
c:\>(for /r %f in (*.Java) do @type %f ) | find /c /v ""
Font: https://superuser.com/questions/959036/what-is-the-windows-equivalent-of-wc-l
Sie können die Ausgabe von type
in find
innerhalb der in(…)
-Klausel einer for /f
-Schleife leiten:
for /f %%A in ('
type "%~dpf1" ^| find /c /v ""
') do set "lineCount=%%A"
Aber die Pfeife startet eine Subshell, was die Sache verlangsamt.
Oder Sie können die Eingabe aus der Datei in find
umleiten, wie folgt:
for /f %%A in ('
find /c /v "" ^< "%~dpf1"
') do set "lineCount=%%A"
Dieser Ansatz gibt Ihnen jedoch eine Antwort 1 weniger als die tatsächliche Anzahl von Zeilen, wenn die Datei mit einer oder mehreren leeren Zeilen endet, wie von den späten foxidrive in Zählzeilen in einer Datei hervorgehoben.
Und dann könnten Sie immer noch versuchen:
find /c /v "" example.txt
Das Problem ist, die Ausgabe des obigen Befehls sieht folgendermaßen aus:
---------- EXAMPLE.TXT: 511
Sie können die Zeichenfolge im Doppelpunkt aufteilen, um die Anzahl zu ermitteln. Es kann jedoch mehr als ein Doppelpunkt geben, wenn der Dateiname einen vollständigen Pfad enthält.
Hier ist meine Meinung zu diesem Problem:
for /f "delims=" %%A in ('
find /c /v "" "%~1"
') do for %%B in (%%A) do set "lineCount=%%B"
Dadurch wird immer die Anzahl in der Variablen gespeichert.
Nur ein letztes kleines Problem… find
behandelt Nullzeichen als Zeilenumbrüche. Wenn sich also hinterlistige Nullen in Ihre Textdatei eingeschlichen haben oder Sie die Zeilen in einer Unicode-Datei zählen möchten, ist diese Antwort nicht für Sie.
Im folgenden Code sind der Variablenname SalaryCount
und 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%
Wenn Sie diese Werte nun in eine CSV-Datei ausgeben müssen, können Sie den folgenden Code verwenden.
@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
Der >
überschreibt den vorhandenen Inhalt der Datei und der >>
fügt die neuen Daten an die vorhandenen Daten an. Die CSV wird in D:\CSVOutputPath generiert.
Die folgende :countLines
-Subroutine akzeptiert zwei Parameter: einen Variablennamen; und einen Dateinamen. Die Anzahl der Zeilen in der Datei wird gezählt, das Ergebnis wird in der Variablen gespeichert und das Ergebnis wird an das Hauptprogramm zurückgegeben.
Der Code verfügt über folgende Funktionen:
(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 =%
Ich weiß, dass es abscheulich aussieht, aber es deckt die meisten Edge-Fälle ab und ist überraschend schnell.