PowerShell:如何计算CSV文件中的行数?

32

我怎样可以使用PowerShell计算CSV文件中行的数量?我尝试了以下方法:

Get-Content -length "C:\Directory\file.csv"
或者
(Get-Content).length "C:\Directory\file.csv"

但是这些会导致错误。

6个回答

62

使用Get-Content和Measure-Object对于小文件来说还好,但两者在处理大文件时效率极低。我曾遇到过大文件的实际问题。

当使用任一方法计算1GB文件中的行数时,Powershell会占用服务器上所有可用的内存(8GB),然后开始向磁盘进行分页。我将其放置了一个小时,但它仍在向磁盘进行分页,所以我终止了它。

我发现的处理大文件的最佳方法是使用IO.StreamReader从磁盘加载文件并使用变量计算每个行。这将内存使用量保持在非常合理的25MB,并且速度快得多,处理1GB文件的行数大约需要30秒,而处理6GB文件的行数需要几分钟。无论您的文件有多大,它都不会占用过多的RAM:

[int]$LinesInFile = 0
$reader = New-Object IO.StreamReader 'c:\filename.csv'
 while($reader.ReadLine() -ne $null){ $LinesInFile++ }

上述代码片段可插入到任何您使用 get-content 或 measure-object 的位置,只需引用 $LinesInFile 变量即可获取文件的行数。


比这里展示的任何其他解决方案都要快。不到5秒钟就可以对一个500mb的csv文件进行排序。 - alextc
7
在使用完毕后,你还需要释放阅读器对象($reader.Dispose()),否则可能会导致文件一直处于打开状态,直到关闭 PowerShell 会话。 - Oleh Nechytailo
2
如果使用PowerShell,请在上面的代码块末尾添加“write-output $LinesInFile”以在屏幕上获取该值。 - Matt M
请注意,最好的做法是指定 while ($null -ne $reader.ReadLine()) { ... },因为比较运算符有时可能像过滤器一样工作。 https://rencore.com/blog/powershell-null-comparison/ - Bacon Bits
1
@Linga 搜索处理文件列表的PowerShell脚本,将我的代码片段插入循环中,并在循环内指定文件名作为变量。 - Geoff Griswald
显示剩余3条评论

43

将它管道传递到 Measure-Object 命令

Import-Csv C:\Directory\file.csv | Measure-Object

5
谢谢,这个似乎有效,但与GNU Unix工具中的wc.exe相比非常慢。 - jrara
3
这是因为wc.exe相当于(Get-Content).Length,虽然比Import-CSV快得多,但正如stej指出的那样,它也是一个潜在的错误解决方案,因为它不会计算多行字段的行数。 - EBGreen
3
好的,请提供需要翻译的内容。 - Franck Dernoncourt

10

一般来说(无论是csv格式还是其他格式)

@(Get-Content c:\file.csv).Length

如果文件只有一行,那么它将会失败。 (你需要使用@前缀...否则如果文件只有一行,它只会计算该行中的字符数量。


如果文件只有一行,则必须使用 @ 前缀,否则将只会统计该行中字符的数量。
Get-Content c:\file.csv | Measure-Object -line

但是,如果任何记录占用了多行,则两者都会失败。那么最好是导入csv并测量:

Import-Csv c:\file.csv | Measure-Object | Select-Object -expand count

最后一个似乎会生成一个错误:Select-Object: 无法扩展属性“count”,因为它没有可扩展的内容。 在第1行第64个字符处:
  • Import-Csv C:\Directory\file.csv | Measure-Object | Select-Object <<<< -expand count
- jrara
奇怪,Measure-Object 应该返回一个具有属性 Count 的对象。试着移除 |Select-Object ...,你就会看到它返回的是什么。 - stej
你可能正在使用 PowerShell v1。在 v1 中,当结果是标量(一个对象)时,“Select-Object -expand propertyName”会抛出错误。升级到v2,问题就解决了。 - Shay Levy
谢谢,是的,我正在使用1.0版本,它是这个问题的一个标签之一。 - jrara
2
我只检查PowerShell标签。并且默默地假设没有人使用v1.0。抱歉 :) - stej
好的,没问题,感谢您的贡献。顺便说一下,我仍在使用Win XP,据我所知,PowerShell 2.0不适用于Win XP? - jrara

3

你可以在PowerShell中简单地使用类Unix命令。

如果你有一个名为test.csv的文件, 那么获取行数的命令是:

gc test.csv | Measure-Object

0

(Import-Csv C:\Directory\file.csv).count 是这些建议中唯一准确的一个。

我尝试了所有其他建议,对于一个有4781行的csv文件,除了这个建议外,所有其他建议都返回了4803。


0

你可以尝试

(Import-Csv C:\Directory\file.csv).count

或者

$a=Import-Csv C:\Directory\file.csv
$a.count

使用这种方法处理大文件时,我会遇到 OutOfMemoryException 异常。使用 Get-Content | Measure-Object 可以在有限的内存量下工作。 - oɔɯǝɹ

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