Powershell搜索目录中与文本匹配的代码文件输入一个txt文件



内部系统到新供应商系统的数据映射项目。第一步是在C#.cs源文件中查找所有出现的当前数据库字段名(确切地说是列名(。正在尝试使用Powershell。最近,我用Get-ChildItem和SelectString创建了PS搜索,效果很好,但搜索字符串数组很小,很容易内联硬编码。但是被移植的应用程序有几百个列名和大量的代码。因此,有了一个包含所有列名的文本文件,Pipleline似乎是一个上帝的工具,可以创建一个基本的交叉引用来进行进一步的分析。然而,除了第一步之外,我无法让Pipeline在任何地方使用外部变量。正在尝试使用-PipelineVariable,$_。和全局变量。经过大量搜索,没有找到任何具体内容。附言:这是我向StackoOverflow提出的第一个问题,请客气。

这是我希望能奏效的,但到目前为止还是成功了。

$inputFile = "C:DataColumnsNames.txt"
$outputFile = "C:DataColumnsUsages.txt"
$arr = [string[]](Get-Content $inputfile)
foreach ($s in $arr) {
Get-ChildItem -Path "C:ProjectFolder*"  -Filter *.cs  -Recurse -ErrorAction SilentlyContinue -Force |
Select-String $s | Select-Object  Path, LineNumber, line | Export-csv $outputfile
}

确实发现这会打印列表一次,但不会打印两次。事实上,以这种方式使用变量似乎只会导致处理跳过任何进一步的管道步骤。

foreach ($s in $arr) {Write-Host $s | Write $s}

如果在Powershell中不可能轻松做到这一点,我的后备方案是使用C#,尽管如果有人能让我正确理解如何在Pipeline中做事,或者构造一个等效的函数,我更愿意使用Powershell。看起来很适合Powershell。

谢谢。

您在循环中调用Export-csv $outputfile,它在每次迭代中重写整个文件,这样只有最后一次迭代的输出才会出现在文件中。

虽然可以使用-Append迭代地附加到输出文件,但值得退一步:Select-String可以接受模式的数组,从而使与中的任何匹配的行被视为匹配。

因此,您的代码可以简化如下:

$inputFile = 'C:DataColumnsNames.txt'
$outputFile = 'C:DataColumnsUsages.txt'
Get-ChildItem C:ProjectFolder -Filter *.cs -Recurse -Force -ea SilentlyContinue |
Select-String -Pattern (Get-Content $inputFile) | 
Select-Object Path, LineNumber, line | 
Export-csv $outputfile

-Pattern (Get-Content $inputFile)将输入文件$inputFile的行作为要匹配的模式的数组传递。

默认情况下,这些行被解释为正则表达式(正则表达式(;要确保它们被视为文字,请将-SimpleMatch添加到Select-String调用中。


这个对后续问题的回答显示了如何在输出中的每一行上匹配的传递给-Pattern的多个模式中包括特定模式。

我认为您希望将每一次出现都附加到csv文件中。您需要获取文件的内容。试试这个:

$inputFile = "C:DataColumnsNames.txt"
$outputFile = "C:DataColumnsUsages.txt"
$arr [string[]](Get-Content $inputfile)
foreach ($s in $arr) {
Get-ChildItem -Path "C:ProjectFolder*"  -Filter *.cs  -Recurse -ErrorAction SilentlyContinue -Force | Foreach {
Get-Content "$_.Fullname" | Select-String $s | Select-Object  Path, LineNumber, line | Export-csv -Append -Path "$outputfile"
}
}

-在powershell v3.0(Windows 8(之前没有引入Append,请尝试以下操作:

$inputFile = "C:DataColumnsNames.txt"
$outputFile = "C:DataColumnsUsages.txt"
$arr [string[]](Get-Content $inputfile)
foreach ($s in $arr) {
Get-ChildItem -Path "C:ProjectFolder*"  -Filter *.cs  -Recurse -ErrorAction SilentlyContinue -Force | Foreach {
Get-Content "$_.Fullname" | Select-String $s | Select-Object  Path, LineNumber, line | ConvertTo-CSV -NoTypeInformation | Select-Object -Skip 1 | Out-File -Append -Path "$outputfile"
}
}

最新更新