我有一段代码,用于将以下内容发送到Linux命令行:wc -l C:/inputdirectory/P*但是,我需要在Windows中运行此脚本,并试图找到等效的命令。find /c /v C:/inputdirectory/P*但是这会抛出一个错误,/v不是一个有效的命令。你能告诉我为什么这不起作用吗?
jei2mxaa1#
来自Eryk Sun:尝试搜索"",即空字符串;只使用反斜杠作为路径分隔符;如果路径中有空格,则用引号引起来:
""
find /c /v "" "C:\inputdirectory\P*"
7vhp5slm2#
注意:如果你只需要一个 * 单个 * 输入文件的行数,一个简单的解决方案(将整个文件加载到内存中)是,例如,(gc file.txt).Count(gc是Get-Content的内置别名)。更快的版本:(gc -ReadCount 0 file.txt).Count
(gc file.txt).Count
gc
Get-Content
(gc -ReadCount 0 file.txt).Count
来自cmd.exe(命令提示符/ a批处理文件),过时:
cmd.exe
find --% /c /v "" "C:\inputdirectory\P*"
注意:--%,停止解析符号,告诉PowerShell将后续参数按原样传递给目标程序(在展开cmd风格的环境变量引用,如%USERNAME%,如果有的话)。在本例中,这会阻止PowerShell解析""和-mistakenly- *,而忽略将其传递 * 到外部目标程序(find.exe)。有关PowerShell在调用外部程序时处理引号时存在的严重问题的总结,请参见this answer。上面的find.exe命令的输出--实际上,任何 * 外部程序 * 的输出都只是 text,在本例中,它看起来像这样:
--%
cmd
%USERNAME%
find.exe
---------- PFILE1.TXT: 42 ---------- PFILE2.TXT: 666 ...
虽然这个**输出对于人类观察者 * 来说很容易理解 ,但它使后续的 * 编程 * 处理变得繁琐*,因为需要进行文本解析。如下所述,使用PowerShell本机命令(cmdlet)提供了更大的灵活性,因为PowerShell命令通常会发出带有 * 类型化属性 * 的 * 对象 *,这极大地促进了后续处理。
选项B( 首选 *):使用PowerShell自己的Measure-Object cmdlet和-Line开关:
Measure-Object
-Line
注意:虽然此命令比find方案更详细,但最终**由于输出 * 对象 * 带有 * 类型化属性 ,提供了更大的灵活性,极大地方便了后续处理*;此外,PowerShell复杂的输出格式化系统提供了用户友好的默认表示。
find
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
File Lines ---- ----- C:\inputdirectory\Pfile1.txt 42 C:\inputdirectory\Pfile2.txt 666 ...
除了更好的输出 * 表示 * 之外,输出的面向对象特性还使得以 * 编程方式处理 * 结果变得更加容易。
例如,如果您希望将输出限制为行数为100或更大的文件,请通过管道连接到以下对上述命令的Where-Object调用:
100
Where-Object
... | Where-Object Lines -ge 100
如果您(另外)希望首先按最高行数排序,请通过管道连接到Sort-Object cmdlet:
Sort-Object
... | Sort-Object -Descending Lines
z0qdvdin3#
使用以下批处理文件(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*
kqqjbcuj4#
Windows中与Linux命令“wc -l”等效的命令是“find /c /v“"""。“/c”选项计算文件中的行数,“/v”指定该命令应计算不包含搜索字符串的行数(在本例中为空)。关于您的错误,似乎Windows中的“find”命令无法识别“/v”选项。相反,您可以将“/v”选项与“findstr”命令一起使用,这是Linux中“grep”命令的Windows等效命令。因此,您应该使用的命令是:
findstr /r /n "^" C:/inputdirectory/P* | find /c ":"
这个命令首先使用“findstr”命令列出文件中所有与正则表达式“^”匹配的行(它与每行的开头匹配)。然后这个命令的输出被管道传输到“find”命令,该命令计算包含冒号“:“的行数(它是由“findstr”命令带“/n”选项添加到每行的开头的)。结果与Linux“wc -l”命令相同。
4条答案
按热度按时间jei2mxaa1#
来自Eryk Sun:
尝试搜索
""
,即空字符串;只使用反斜杠作为路径分隔符;如果路径中有空格,则用引号引起来:7vhp5slm2#
注意:如果你只需要一个 * 单个 * 输入文件的行数,一个简单的解决方案(将整个文件加载到内存中)是,例如,
(gc file.txt).Count
(gc
是Get-Content
的内置别名)。更快的版本:
(gc -ReadCount 0 file.txt).Count
来自
cmd.exe
(命令提示符/ a批处理文件),过时:从 PowerShell,您有两个选择:
备选办法A( 次优 *):也使用已接受的答案,但要做一个小调整:
注意:
--%
,停止解析符号,告诉PowerShell将后续参数按原样传递给目标程序(在展开cmd
风格的环境变量引用,如%USERNAME%
,如果有的话)。在本例中,这会阻止PowerShell解析
""
和-mistakenly- *,而忽略将其传递 * 到外部目标程序(find.exe
)。有关PowerShell在调用外部程序时处理引号时存在的严重问题的总结,请参见this answer。
上面的
find.exe
命令的输出--实际上,任何 * 外部程序 * 的输出都只是 text,在本例中,它看起来像这样:虽然这个**输出对于人类观察者 * 来说很容易理解 ,但它使后续的 * 编程 * 处理变得繁琐*,因为需要进行文本解析。
如下所述,使用PowerShell本机命令(cmdlet)提供了更大的灵活性,因为PowerShell命令通常会发出带有 * 类型化属性 * 的 * 对象 *,这极大地促进了后续处理。
选项B( 首选 *):使用PowerShell自己的
Measure-Object
cmdlet和-Line
开关:注意:虽然此命令比
find
方案更详细,但最终**由于输出 * 对象 * 带有 * 类型化属性 ,提供了更大的灵活性,极大地方便了后续处理*;此外,PowerShell复杂的输出格式化系统提供了用户友好的默认表示。上面的**输出 * 对象 ,每个对象都有一个
.File
和.Lines
属性*,PowerShell默认打印如下:除了更好的输出 * 表示 * 之外,输出的面向对象特性还使得以 * 编程方式处理 * 结果变得更加容易。
例如,如果您希望将输出限制为行数为
100
或更大的文件,请通过管道连接到以下对上述命令的Where-Object
调用:如果您(另外)希望首先按最高行数排序,请通过管道连接到
Sort-Object
cmdlet:z0qdvdin3#
如何统计一组文件的行数?
使用以下批处理文件(CountLines.cmd):
用法:
进一步阅读
kqqjbcuj4#
Windows中与Linux命令“wc -l”等效的命令是“find /c /v“"""。“/c”选项计算文件中的行数,“/v”指定该命令应计算不包含搜索字符串的行数(在本例中为空)。
关于您的错误,似乎Windows中的“find”命令无法识别“/v”选项。相反,您可以将“/v”选项与“findstr”命令一起使用,这是Linux中“grep”命令的Windows等效命令。因此,您应该使用的命令是:
这个命令首先使用“findstr”命令列出文件中所有与正则表达式“^”匹配的行(它与每行的开头匹配)。然后这个命令的输出被管道传输到“find”命令,该命令计算包含冒号“:“的行数(它是由“findstr”命令带“/n”选项添加到每行的开头的)。结果与Linux“wc -l”命令相同。