如何使用批处理脚本计算文本文件中的行数并将值存储到变量中?

发布于 2024-11-01 17:04:46 字数 355 浏览 1 评论 0原文

我想计算文本文件中的行数,然后必须将值存储到环境变量中。计算行数的命令是

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

我提到的问题如何使用bat脚本将命令表达式的结果存储在变量中? 然后我尝试了,

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

我收到错误消息,

FIND: Parameter format not correct

我怎样才能摆脱这个错误。

I want to count the no of lines in a text file and then the value has to be stored into a environment variable. The command to count the no of lines is

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

I refered the question How to store the result of a command expression in a variable using bat scripts?
Then I tried,

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

I am getting the error message,

FIND: Parameter format not correct

How could i get rid of this error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

或十年 2024-11-08 17:04:46

有一种比所有其他方法简单得多的方法。

find /v /c "" filename.ext

显然,这是遗留下来的 MS-DOS 时代的产物。更多信息请参见:https://devblogs.microsoft.com/oldnewthing/20110825- 00/?p=9803

使用示例:

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

如果您的 Android 设备已连接到您的 PC 并且您的路径上有 Android SDK,则会打印出已安装的应用程序数量在您的设备上。

There is a much simpler way than all of these other methods.

find /v /c "" filename.ext

Holdover from the legacy MS-DOS days, apparently. More info here: https://devblogs.microsoft.com/oldnewthing/20110825-00/?p=9803

Example use:

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

If your android device is connected to your PC and you have the android SDK on your path, this prints out the number of apps installed on your device.

恬淡成诗 2024-11-08 17:04:46

您可以使用 FOR /F 循环将输出分配给变量。

我使用 cmd-variable,因此无需转义 cmd-string 中的管道或其他字符,因为延迟扩展将“未更改”的字符串传递给 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%

You could use the FOR /F loop, to assign the output to a variable.

I use the cmd-variable, so it's not neccessary to escape the pipe or other characters in the cmd-string, as the delayed expansion passes the string "unchanged" to the 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%
戈亓 2024-11-08 17:04:46

受到之前帖子的启发,
更短的方法:

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

行数

尝试一下。它在我的控制台中工作。

编辑:(

删除了“$”符号)

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

$ 将数字减少 1,因为它接受第一行作为字段名称,然后计算行数。

Inspired by the previous posts,
a shorter way of doing so:

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

The number of lines

Try it. It works in my console.

EDITED:

(the "$" sign removed)

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

$ reduces the number by 1 because it is accepting the first row as Field name and then counting the number of rows.

旧夏天 2024-11-08 17:04:46

试试这个:

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

它消除了额外的 FindStr 并且不需要扩展。


- 已编辑以使用 ChrisJJ 的重定向建议。删除 TYPE 命令使其速度提高了三倍。

Try this:

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

It eliminates the extra FindStr and doesn't need expansion.


- edited to use ChrisJJ's redirect suggestion. Removal of the TYPE command makes it three times faster.

独享拥抱 2024-11-08 17:04:46

@Tony:您甚至可以摆脱 type %file% 命令。

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

对于长文件,这应该更快。

@Tony: You can even get rid of the type %file% command.

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

For long files this should be even quicker.

一抹苦笑 2024-11-08 17:04:46

我通常使用类似这样的东西
for /f %%a in (%_file%) do (set /a Lines+=1)

I usually use something more like this
for /f %%a in (%_file%) do (set /a Lines+=1)

猫九 2024-11-08 17:04:46
for /f "usebackq" %A in (`TYPE c:\temp\file.txt ^| find /v /c "" `) do set numlines=%A

在批处理文件中,使用 %%A 而不是 %A

for /f "usebackq" %A in (`TYPE c:\temp\file.txt ^| find /v /c "" `) do set numlines=%A

in a batch file, use %%A instead of %A

痕至 2024-11-08 17:04:46

完美的解决方案是:

FOR /F %%i IN ('TYPE "Text file.txt" ^| FIND /C /V ""') DO SET Lines=%%i

The perfect solution is:

FOR /F %%i IN ('TYPE "Text file.txt" ^| FIND /C /V ""') DO SET Lines=%%i
阳光下的泡沫是彩色的 2024-11-08 17:04:46

我发现这个解决方案最适合创建一个自我维护的日志文件:

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

包括的环境变量是%clientname%远程客户端的计算机名%Date%是当前日期和%Time%当前时间。 :NEXT 在获取文件中的行数后调用。如果文件行数大于 %maxlines% 变量,它将转到 :EXITLOOP 并覆盖该文件,并使用第一行信息创建一个新文件。如果它小于 %maxlines% 变量,它只是将该行添加到当前文件中。

I found this solution to work best for creating a log file that maintains itself:

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

Environmental variables included are %clientname% the computername of the remote client %Date% is the current date and %Time% the current time. :NEXT is called after getting the number of lines in the file. If the file line count is greater than the %maxlines% variable it goes to the :EXITLOOP where it overwrites the file, creating a new one with the first line of information. if it is less than the %maxlines% variable it simply adds the line to the current file.

默嘫て 2024-11-08 17:04:46

下面的 :countLines 子例程接受两个参数:变量名;和一个文件名。统计文件中的行数,将结果存储在变量中,并将结果传回主程序。

该代码具有以下功能:

  • 读取带有 Windows 或 Unix 行结尾的文件。
  • 处理 Unicode 以及 ANSI/ASCII 文本文件。
  • 应对极长的线路。
  • 不会被空字符所困扰。
  • 读取空文件时引发错误。
  • 计数超出 Batch max int 限制 (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 =%

我知道它看起来很丑陋,但它涵盖了大多数边缘情况,而且速度快得惊人。

The :countLines subroutine below accepts two parameters: a variable name; and a filename. The number of lines in the file are counted, the result is stored in the variable, and the result is passed back to the main program.

The code has the following features:

  • Reads files with Windows or Unix line endings.
  • Handles Unicode as well as ANSI/ASCII text files.
  • Copes with extremely long lines.
  • Isn’t fazed by the null character.
  • Raises an error on reading an empty file.
  • Counts beyond the Batch max int limit of (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 =%

I know it looks hideous, but it covers most edge-cases and is surprisingly fast.

遮了一弯 2024-11-08 17:04:46

您不需要使用查找。

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

这会迭代文件中的所有行,并将每行的计数器变量加 1。

You don't need to use find.

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

This iterates all lines in the file and increases the counter variable by 1 for each line.

这个俗人 2024-11-08 17:04:46

只是:

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

字体:https://superuser.com/questions/959036/ wc-l 的 windows 等价物是什么

Just:

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

海之角 2024-11-08 17:04:46

对于在 Windows 上安装了 git bash 的人来说,这是一个不错的惊喜:只需简单的旧 linux wc -l 就可以在那里工作

One nice surprise is for one who has git bash on his windows: just plain old linux wc -l <filename> will works for you there

你的往事 2024-11-08 17:04:46

在下面的代码中,变量名称是 SalaryCountTaxCount

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

现在,如果您需要将这些值输出到 csv 文件,您可以使用以下代码。

@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

> 将覆盖文件的现有内容,>> 将把新数据附加到现有数据中。 CSV 将在 D:\CSVOutputPath 中生成

In the below code, the variable name are SalaryCount and 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%

Now if you need to output these values to a csv file, you could use the below code.

@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

The > will overwrite the existing content of the file and the >> will append the new data to existing data. The CSV will be generated in D:\CSVOutputPath

死开点丶别碍眼 2024-11-08 17:04:46

您可以将 type 的输出通过管道传送到 for /f 循环的 in(…) 子句中的 find

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

但是管道启动了一个子 shell,这会减慢速度。

或者,您可以将文件中的输入重定向到 find 中,如下所示:

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

但是,如果文件以一个或多个空行结尾,则这种方法会给您一个比实际行数少 1 的答案,如所戏弄的由已故的 foxidrive计算文件中的行数

然后,您总是可以尝试:

find /c /v "" example.txt

问题是,上述命令的输出如下所示:

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

您可以拆分冒号上的字符串来获取计数,但如果文件名具有完整的冒号,则可能会有多个冒号小路。

这是我对这个问题的看法:

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

这将始终将计数存储在变量中。

最后一个小问题... find 将空字符视为换行符。因此,如果偷偷摸摸的空值潜入您的文本文件,或者您想要计算 Unicode 文件中的行数,那么这个答案不适合您。

You can pipe the output of type into find inside the in(…) clause of a for /f loop:

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

But the pipe starts a subshell, which slows things down.

Or, you could redirect input from the file into find like so:

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

But this approach will give you an answer 1 less than the actual number of lines if the file ends with one or more blank lines, as teased out by the late foxidrive in counting lines in a file.

And then again, you could always try:

find /c /v "" example.txt

The trouble is, the output from the above command looks like this:

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

You could split the string on the colon to get the count, but there might be more than one colon if the filename had a full path.

Here’s my take on that problem:

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

This will always store the count in the variable.

Just one last little problem… find treats null characters as newlines. So if sneaky nulls crept into your text file, or if you want to count the lines in a Unicode file, this answer isn’t for you.

榆西 2024-11-08 17:04:46

你也可以尝试

set n=0 & for /f "tokens=*" %a in (text.txt) do set/a n=!n!+1
echo !n!

You can also try

set n=0 & for /f "tokens=*" %a in (text.txt) do set/a n=!n!+1
echo !n!
未央 2024-11-08 17:04:46

还可以用通配符*进行标记,方便分组文件统计。

Z:\SQLData>find /c /v "" FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_*.txt

结果

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS01_V1.TXT:2041

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIOST00_V1.TXT:315938

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS00_V1 .TXT: 0

---- ------ FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_CNTPTF00_V1.TXT:277

You can also mark with a wildcard symbol * to facilitate group files to count.

Z:\SQLData>find /c /v "" FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_*.txt

Result

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS01_V1.TXT: 2041

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIOST00_V1.TXT: 315938

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_AVIFRS00_V1.TXT: 0

---------- FR_OP133_OCCURENCES_COUNT_PER_DOCUMENTS_CNTPTF00_V1.TXT: 277

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文