简体   繁体   English

Oneliner计算文件每行中的选项卡数量

[英]Oneliner to count the number of tabs in each line of a file

I have a file that is tab delimited. 我有一个以制表符分隔的文件。 I would like a powershell script that counts the number of tabs in each line. 我想要一个powershell脚本来计算每行中的选项卡数量。 I came up with this: 我想出了这个:

${C:\tabfile.txt} |% {$_} | Select-String \t | Measure-Object | fl count

it yields 3, Which is the number of lines in the file. 它产生3,这是文件中的行数。

any pointers to what I'm doing wrong? 我做错了什么指针? I would like it to print a single number for each line in the file. 我希望它为文件中的每一行打印一个数字。

A couple issues with your code, but they all revolve around grouping / array management / nested loops. 您的代码有两个问题,但它们都围绕分组/数组管理/嵌套循环。

gc test.txt | % { ($_ | select-string `t -all).matches | measure | select count }
  • After reading the text file into lines, you need to wrap the rest of the pipeline into a scriptblock. 将文本文件读入行后,需要将管道的其余部分包装成一个脚本块。 Otherwise downstream cmdlets cannot distinguish which elements came from the "current" line. 否则,下游cmdlet无法区分哪些元素来自“当前”行。 The PS pipeline is all about dealing with objects one by one -- there's no concept of nested arrays or iterator state or anything else -- blind enumeration. PS管道就是一个接一个地处理对象 - 没有嵌套数组或迭代器状态或其他任何东西的概念 - 盲目枚举。
  • You need to specify -AllMatches, otherwise select-string will stop as soon as it finds the first match on each line. 您需要指定-AllMatches,否则select-string将在每行找到第一个匹配后立即停止。 You then need to get the Matches property from its nominal resultset to get the "inner resultset" of this intra-line matching. 然后,您需要从其标称结果集中获取Matches属性,以获取此内部匹配的“内部结果集”。

First attempt, not very sophisticated: 第一次尝试,不是很复杂:

gc .\tabfile.txt | % { ($_ -split "`t").Count - 1 }

Utilizing the fact here, that when I split the string at tab characters, I'll get an array with one more item than there are tabs in the line. 利用这里的事实,当我将字符串拆分为制表符时,我会得到一个数组,其中包含的项目多于该行中的制表符。

Another approach, avoiding splitting the lines: 另一种方法,避免分裂线:

gc .\tabfile.txt | % { ([char[]] $_ -eq "`t").Count }

Strings can be cast to char[] (also there is the ToCharArray() method), then I am using the fact that comparison operators work differently on collections, by returning all matching items, instead of a boolean. 字符串可以转换为char[] (也有ToCharArray()方法),然后我通过返回所有匹配的项而不是布尔值来使用比较运算符对集合的工作方式不同的事实。 So the comparison there returns an array containing all tabs from the original line from which I just need to get the number of items. 因此比较会返回一个数组,其中包含原始行中的所有选项卡,我只需从中获取项目数。

And yet another option if you are running V2. 如果您运行V2,还有另一种选择。

select-string \t c:\tabfile.txt -All | 
    %{"$($_.matches.count) tabs on $($_.LineNumber)"}

Another option: 另外一个选项:

$content = Get-Content file.txt | Out-String
[regex]::matches($content,"\t").count

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM