Windows中与Linux命令wc -l相当的是什么?

5
我有一段代码,旨在将以下内容发送到Linux命令行:

wc -l C:/inputdirectory/P*

然而,在Windows中运行此脚本时,我需要找到相应的命令。我尝试过以下命令:

find /c /v C:/inputdirectory/P*

但是这会抛出一个错误,/v 不是有效的命令。请问为什么会出现这种情况?
*注意,命令本身并没有写 "inputdirectory",它有正确的目录,只是太繁琐和私密了,无法打出来。

2
尝试搜索 "",即空字符串;仅使用 反斜杠 作为路径分隔符;如果路径中有空格,请将其引用起来:find /c /v "" "C:\inputdirectory\P*" - Eryk Sun
3
Cygwin为Windows提供了很多移植自Linux的实用工具。网站上宣传口号是“在Windows上获得Linux的感觉”。 - LMC
2
如果你使用的是Win10操作系统,那么你就可以使用WSL来获取所有Linux提供的好东西。 - SomeWittyUsername
这里有一个很好的答案。https://dev59.com/kVQI5IYBdhLWcg3w-Qhi#54893466 - lit
3个回答

3
感谢 Eryk Sun 的贡献:
尝试搜索空字符串"",即一个空的字符串;只使用反斜杠作为路径分隔符,并在路径中有空格时加引号:
find /c /v "" "C:\inputdirectory\P*"

1
FIND /C /V并不完全等同于wc -l。它会输出一串破折号,后跟文件名和计数。---------- README.TXT: 41wc -l只会输出计数。 - lit

3

注意:如果您只需要单个输入文件的行数,一个简单的解决方案(将整个文件加载到内存中)是,例如,(gc file.txt).CountgcGet-Content 的内置别名)。
更快的版本:(gc -ReadCount 0 file.txt).Count

cmd.exe(命令提示符 / 批处理文件)中,这已经是过时的

PowerShell,您有两个选项

  • 选项 A(次优:也使用接受的答案,但稍作修改:
find --% /c /v "" "C:\inputdirectory\P*"

注意:--%,停止解析符号,告诉PowerShell将随后的参数按原样传递给目标程序(在扩展cmd风格的环境变量引用(如%USERNAME%)之后,如果有的话)。
在这种情况下,这可以防止PowerShell解析""和-mistakenly- 疏忽地未通过到外部目标程序(find.exe)。
对于PowerShell在调用外部程序时处理引号的高度问题的摘要,请参见this answer
上述find.exe命令的输出-实际上,任何外部程序的输出都是纯文本,本例中看起来像这样:
---------- PFILE1.TXT: 42

---------- PFILE2.TXT: 666

...

虽然这个输出对于人类观察者来说很容易理解,但是它会使随后的编程处理变得复杂,因为需要进行文本解析。

使用 PowerShell 本地命令(cmdlet),如下所述,提供了更多的灵活性,因为 PowerShell 命令通常发出带有类型属性的对象,这极大地方便了随后的处理。


  • 选项 B(首选使用 PowerShell 自带的 Measure-Object 命令和 -Line 开关:

注意:虽然这个命令比 find 解决方案更加详细,但它最终提供了更多的灵活性,因为它输出具有类型属性的对象,这极大地便于后续处理;此外,PowerShell 的复杂输出格式系统提供了用户友好的默认表示。

Get-Item -Path "C:\inputdirectory\P*" -PipelineVariable file | ForEach-Object {
  Get-Content -LiteralPath $file |
    Measure-Object -Line |
      Select-Object @{ Name='File'; Expression={ $file } }, Lines
}

以上代码输出对象,每个对象都有一个.File.Lines属性,默认情况下PowerShell会打印如下内容:
File                         Lines
----                         -----
C:\inputdirectory\Pfile1.txt    42
C:\inputdirectory\Pfile2.txt   666
...

除了输出更好的呈现外,输出的面向对象的特性使得编程处理结果变得容易。

例如,如果您想将输出限制为行数大于等于100的文件,则可以将其管道到以下Where-Object调用命令:

... | Where-Object Lines -ge 100

如果您还想按最高行数排序,可以将其管道传输到Sort-Object命令:

... | Sort-Object -Descending Lines

这个答案的冗长部分很糟糕。更简洁的方法在以下链接中描述:https://superuser.com/questions/959036/what-is-the-windows-equivalent-of-wc-l。简而言之:`cat file.txt | Measure-Object -line`。 - MarkHu
1
@MarkHu,你的命令只是(a)将Get-Content替换为其在Windows上的cat别名,(b)对单个输入文件应用Measure-Object -Line,并且(b)不产生wc -l会产生的输出。换句话说:你正在回答一个不同得多、更简单的问题,解决方案更短也就不足为奇了。如果你只想知道一个文件的行数,请使用(cat file.txt).Count - mklement0
@MarkHu,关于链接的SU帖子中显示的(ls | Measure-Object -line).Lines:只需使用(gci).Count即可-根本不需要使用Measure-Object。(gciGet-ChildItem的内置别名,在Windows上也是ls;但是,在类Unix平台上,ls指的是外部的/bin/ls实用程序)。 - mklement0

2

如何计算一组文件中的行数?

使用以下批处理文件(CountLines.cmd):

@echo off
Setlocal EnableDelayedExpansion
for /f "usebackq" %%a in (`dir /b %1`)  do (
  for /f "usebackq" %%b in (`type %%a ^| find "" /v /c`) do (
    set /a lines += %%b
    )
  )
echo %lines%
endlocal

使用方法:

CountLines C:/inputdirectory/P*

更多阅读资料

  • Windows CMD命令行A至Z索引 - 这是一个与Windows命令行相关的优秀参考资料。
  • dir - 显示文件和子文件夹列表。
  • find - 在文件中搜索文本字符串,并显示包含该字符串的所有行。
  • for /f - 对另一个命令的结果执行循环命令。

1
如果我们通过管道将文件typefind中,很明显没有文件名用于汇总标题,因此find只会输出行数。内部的for /f“循环”提取此结果,并在这种情况下将其添加到所有已处理文件的运行总行数中。 - Eryk Sun
这是一个有趣的练习,可以报告跨多个文件的总行数,但这不是wc -l C:/inputdirectory/P*所做的;后者以<count> <file>的形式报告每个输入文件的计数,这也是当传递文件参数时find.exe直接执行的操作,除了格式细节上的差异。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接