2009-06-09 2 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 
+0

'LineNumber'의 실제 정수를'LineNumber ________ etc'라는 문자가없는 변수에 저장하는 방법이 있습니까 –

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/-end 스크립트 블록이를 단순화 할 수 있어야합니다.)

+0

{$ _._ -match $ regex} | '하고 있지만, 그것이 결과를 얻지 못하게하는 선이다. 그게 뭐야? 또한 $ _. FileName 및 $ _. Line을 $ FileName 및 $ Line으로 변경하여 실행해야합니다. –

+0

@Macho : Typo ...는 $ _이어야합니다. – Richard

+0

다른 답변을 참고하십시오 : select-string은 이미 파일 이름과 행 번호를 캡처합니다. – Richard

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을 사용하여 코드를 작성할 수 있다는 느낌이 들지만 코드가 짧아 질 수 있습니다.

+0

이것은 질문의 범위를 벗어 났지만 와우 ... 이것은 굉장했습니다. 감사!!!! 나는 이것을 사용할 것이다. –

+0

예, 범위를 넘어서지만 유용 할 수 있다고 생각했습니다. 그 외에도 재미있었습니다 :) 블록 사이의 빈 줄을 일치시키는 데 관심이 있다면 알려주십시오. 나는 그 대본을 적용하려고 노력할 것이다. – stej

관련 문제