Обновление до 1.6.0_30 также работало для меня. Microsoft выпустила заявление , объявляющее об исправлении в первом квартале 2012 года. Похоже, это уязвимость Java (BEAST).
Можно сделать:
dir c:\codeishere -filter *.cs -recurse | select-string -Pattern '//.*;' | select Line,LineNumber,Filename
gci c:\codeishere *.cs -r | select-string "//.*;"
Командлет select-string
уже делает именно то, что вы просите, хотя отображаемое имя файла является относительным путем.
Лично я бы пошел еще дальше. Я хотел бы подсчитать количество следующих подряд строк. Затем выведите имя файла, количество строк и сами строки. Вы можете отсортировать результат по количеству строк (кандидаты на удаление?). Обратите внимание, что мой код не учитывается с пустыми строками между строками с комментариями, поэтому эта часть рассматривается как два блока кода с комментариями:
// int a = 10;
// int b = 20;
// DoSomething()
// SomethingAgain()
Вот мой код.
$Location = "c:\codeishere"
$occurences = get-ChildItem $Location *cs -recurse | select-string '//.*;'
$grouped = $occurences | group FileName
function Compute([Microsoft.PowerShell.Commands.MatchInfo[]]$lines) {
$local:lastLineNum = $null
$local:lastLine = $null
$local:blocks = @()
$local:newBlock = $null
$lines |
% {
if (!$lastLineNum) { # first line
$lastLineNum = -2 # some number so that the following if is $true (-2 and lower)
}
if ($_.LineNumber - $lastLineNum -gt 1) { #new block of commented code
if ($newBlock) { $blocks += $newBlock }
$newBlock = $null
}
else { # two consecutive lines of commented code
if (!$newBlock) {
$newBlock = '' | select File,StartLine,CountOfLines,Lines
$newBlock.File, $newBlock.StartLine, $newBlock.CountOfLines, $newBlock.Lines = $_.Filename,($_.LineNumber-1),2, @($lastLine,$_.Line)
}
else {
$newBlock.CountOfLines += 1
$newBlock.Lines += $_.Line
}
}
$lastLineNum=$_.LineNumber
$lastLine = $_.Line
}
if ($newBlock) { $blocks += $newBlock }
$blocks
}
# foreach GroupInfo objects from group cmdlet
# get Group collection and compute
$result = $grouped | % { Compute $_.Group }
#how to print
$result | % {
write-host "`nFile $($_.File), line $($_.StartLine), count of lines: $($_.CountOfLines)" -foreground Green
$_.Lines | % { write-host $_ }
}
# you may sort it by count of lines:
$result2 = $result | sort CountOfLines -desc
$result2 | % {
write-host "`nFile $($_.File), line $($_.StartLine), count of lines: $($_.CountOfLines)" -foreground Green
$_.Lines | % { write-host $_ }
}
Если у вас есть идеи, как улучшить код, опубликуйте его! У меня такое ощущение, что я мог бы сделать это с помощью каких-нибудь стандартных командлетов, и код мог бы быть короче ..
Я бы сделал что-то вроде:
dir $location -inc *.cs -rec | `
%{ $file = $_; $n = 0; get-content $_ } | `
%{ $_.FileName = $file; $_.Line = ++$n; $_ } | `
?{ $_ -match $regex } | `
%{ "{0}:{1}: {2}" -f ($_.FileName, $_.Line, $_)}
Т.е. добавить дополнительные свойства к строке, чтобы указать имя файла и номер строки, которые могут быть переданы по конвейеру после совпадения регулярного выражения.
(Использование блоков сценариев -begin / -end в ForEach-Object
должно упростить это.)