2009-06-09 6 views
4

Je pense que nous avons un tas de code commenté dans notre source, et plutôt que de le supprimer immédiatement, nous l'avons laissé. Maintenant, je voudrais faire un peu de nettoyage. Donc, en supposant que j'ai un assez bon RegEx pour trouver des commentaires (le RegEx ci-dessous est simple et je pourrais développer en fonction de nos normes de codage), comment puis-je prendre les résultats du fichier que j'ai lu et sorti ce qui suit:Utilisez Powershell pour imprimer le numéro de ligne correspondant au code

  • Nom du fichier
  • Numéro de ligne
  • la ligne de code

je pense avoir la base d'une réponse, mais je ne sais pas comment prendre la fil e que j'ai lu et analysé avec RegEx et le cracher dans ce format.

Je ne cherche pas la solution parfaite - je veux juste trouver de gros blocs de code commenté. En regardant le résultat et en voyant un tas de fichiers avec le même nom et les numéros de ligne séquentiels, je devrais être en mesure de le faire.

$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? 
} 

Répondre

12

Vous pouvez faire:

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

Y at-il un moyen pour moi de stocker l'entier réel de 'LineNumber' dans une variable sans avoir le texte' LineNumber ________ etc' –

1

je regardais faire quelque chose comme:

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

à savoir ajouter des propriétés supplémentaires à la chaîne pour spécifier le nom de fichier et le numéro de ligne, qui peuvent être transportés dans le pipeline après la correspondance de la regex.

(En utilisant ForEach-Object « s -Début/-end blocs de script doivent être en mesure de simplifier.)

+0

Je ne sais pas quoi? {$ _._ -match $ regex} | 'est en train de faire, mais c'est la ligne qui semble m'empêcher d'obtenir des résultats. Qu'est-ce que ça fait? En outre, j'ai dû changer $ _. FileName et $ _. Ligne à $ FileName et $ Line pour l'exécuter –

+0

@Macho: Typo ... will ix, devrait être juste $ _. – Richard

+0

Notez les autres réponses: select-string capture déjà le nom de fichier et le numéro de ligne. – Richard

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

L'applet de commande select-string fait déjà exactement ce que vous demandons, bien que le nom de fichier affiché soit un chemin relatif.

2

J'irais personnellement plus loin. Je voudrais calculer le nombre de lignes suivantes consécutives. Ensuite, imprimez le nom du fichier, le nombre de lignes et les lignes elles-mêmes. Vous pouvez trier le résultat par nombre de lignes (candidats à la suppression?). Notez que mon code ne compte pas avec des lignes vides entre les lignes de commentaires, de sorte que cette partie est considérée comme deux blocs de code commenté:

// int a = 10; 
// int b = 20; 

// DoSomething() 
// SomethingAgain() 

Voici mon code.

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

Si vous avez une idée de la façon d'améliorer le code, postez le! J'ai le sentiment que je pourrais le faire en utilisant des cmdlets standard et le code pourrait être plus court ..

+0

C'était au-delà de la portée de la question, mais wow ... c'était génial. Merci!!!! Je vais utiliser celui-ci. –

+0

Oui, au-delà de la portée, mais j'ai pensé que cela pourrait être utile. En plus, c'était amusant :) Si vous étiez intéressé à faire correspondre les lignes vides entre les blocs, faites le moi savoir. J'essaierais d'adapter le script. – stej

Questions connexes