2009-06-09 50 views
4

我認爲我們在源代碼中有一堆註釋掉的代碼,而不是立即刪除它,我們剛剛離開它。現在我想做一些清理。使用Powershell打印出符合RegEx的代碼行號

因此,假設我有一個足夠好的RegEx來查找註釋(下面的RegEx很簡單,我可以根據我們的編碼標準對其進行擴展),我該如何獲取我讀取和輸出的文件的結果以下:

  • 行號
  • 的代碼

實際的線,我認爲我這裏有一個答案的基礎上,但我不知道該怎麼走FIL e,我已經閱讀並用RegEx解析並以此格式吐出。

我不是在尋找完美的解決方案 - 我只是想找到註釋掉代碼的大塊。通過查看結果並看到一堆具有相同名稱和順序行號的文件,我應該可以做到這一點。

$Location = "c:\codeishere" 

[regex]$Regex = "//.*;" #simple example - Will expand on this... 

$Files = get-ChildItem $Location -include *cs -recurse 
foreach ($File in $Files) { 
    $contents = get-Content $File 
    $Regex.Matches($contents) | WHAT GOES HERE? 
} 

回答

12

你可以這樣做:

dir c:\codeishere -filter *.cs -recurse | select-string -Pattern '//.*;' | select Line,LineNumber,Filename 
1

我想看看做這樣的事情:

dir $location -inc *.cs -rec | ` 
    %{ $file = $_; $n = 0; get-content $_ } | ` 
    %{ $_.FileName = $file; $_.Line = ++$n; $_ } | ` 
    ?{ $_ -match $regex } | ` 
    %{ "{0}:{1}: {2}" -f ($_.FileName, $_.Line, $_)} 

即爲字符串添加額外的屬性以指定文件名和行號,這可以在正則表達式匹配後通過管道傳送。

(使用ForEach-Object的-BEGIN /末端腳本塊應該能對此進行簡化。)

+0

我不知道什麼?{$ _._ -match $ regex} | `在做,但這是似乎阻止我獲得結果的線。這是做什麼的? 此外,我不得不改變$ _。FileName和$ _。Line到$ FileName和$ Line來讓它運行 – 2009-06-09 20:29:50

+0

@Macho:Typo ...將ix,應該只是$ _。 – Richard 2009-06-10 07:25:49

+0

請注意其他答案:select-string已經捕獲了文件名和行號。 – Richard 2009-06-10 07:29:14

2
gci c:\codeishere *.cs -r | select-string "//.*;" 

select-string cmdlet的已經不正是你'要求,雖然顯示的文件名是相對路徑。

2

我會親自更進一步。我想計算連續跟隨的行數。然後打印文件名,行數和行數本身。您可以按行數(候選人刪除?)對結果進行排序。 請注意,我的代碼不註釋行之間的空行數,所以這部分被認爲是註釋代碼兩大塊:

// 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 $_ } 
} 

如果您有任何想法如何改進代碼,請發佈!我有一種感覺,我可以使用一些標準的cmdlet,代碼可以更短。