What is the windows equivalent of Linux command wc

2020-03-24 05:36发布

I have a piece of code that is meant to send the following to the linux command line:

wc -l C:/inputdirectory/P*

However, I need to run this script in Windows, and am trying to find the equivalent command. I have tried

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

But this throws an error, that /v is not a valid command. Can you please tell me why this isn't working?

*note, the command itself doesn't say "inputdirectory", it has the correct directory, it's just too tedious and private to type out

3条回答
趁早两清
2楼-- · 2020-03-24 06:11

Courtesy of Eryk Sun:

Try searching for "", i.e. an empty string; use only backslash as the path separator; and quote the path if it has spaces in it:

find /c /v "" "C:\inputdirectory\P*"
查看更多
混吃等死
3楼-- · 2020-03-24 06:26

From cmd.exe (the Command Prompt / a batch file), which is obsolescent:

From PowerShell, you have two options:

  • Option A (suboptimal): Use the accepted answer too, with a small tweak:
find --% /c /v "" "C:\inputdirectory\P*"

Note: --%, the stop-parsing symbol, tells PowerShell to pass subsequent arguments through as-is to the target program (after expanding cmd-style environment-variable references such as %USERNAME%, if any).

In the case at hand, this prevents PowerShell from parsing "" and - mistakenly - neglecting to pass it through to the external target program (find.exe).

For a summary of PowerShell's highly problematic handling of quotes when calling external programs, see this answer.

Output from the above find.exe command - and, indeed, any external program, is just text, and in this case it looks something like this:

---------- PFILE1.TXT: 42

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

...

While this output is easy to grasp for a human observer, it makes subsequent programmatic processing cumbersome, because text parsing is required.

Using a PowerShell-native command (cmdlet), as described below, offers more flexibility, because PowerShell commands typically emit objects with typed properties, which greatly facilitates subsequent processing.


  • Option B (preferred): Use PowerShell's own Measure-Object cmdlet with the -Line switch:

Note: While this command is more verbose than the find solution, it ultimately offers more flexibility due to outputting objects with typed properties, which greatly facilitates subsequent processing; additionally, PowerShell's sophisticated output-formatting system offers user-friendly default representations.

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

The above outputs objects that have a .File and .Lines property each, which PowerShell prints as follows by default:

File                         Lines
----                         -----
C:\inputdirectory\Pfile1.txt    42
C:\inputdirectory\Pfile2.txt   666
...

In addition to a nicer presentation of the output, the object-oriented nature of the output makes it easy to programmatically process the results.

For instance, if you wanted to limit the output to those files whose line count is 100 or greater, pipe to the following Where-Object call to the above command:

... | Where-Object Lines -ge 100

If you (additionally) wanted to sort by highest line count first, pipe to the Sort-Object cmdlet:

... | Sort-Object -Descending Lines
查看更多
女痞
4楼-- · 2020-03-24 06:29

How can I count the lines in a set of files?

Use the following batch file (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

Usage:

CountLines C:/inputdirectory/P*

Further Reading

  • An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
  • dir - Display a list of files and subfolders.
  • find - Search for a text string in a file & display all the lines where it is found.
  • for /f - Loop command against the results of another command.
查看更多
登录 后发表回答