使用powershell 2替换文件中的多行文本(代码)

时间:2015-03-05 09:12:00

标签: powershell visual-studio-2013 powershell-v2.0 nuget-package

我正忙于创建一个仅在内部使用的Nuget包,它将安装其他依赖包,Ninject就是其中之一。

安装后,NinjectWebCommon.cs文件将添加到项目的App_Start文件夹中。我的自定义程序包要求以下列方式修改文件:(仅显示部分代码)

//code above removed... 
using Ninject;
using Ninject.Web.Common;
//modified this part already - refer to block quote 1 on how i did it
using mylibrary.whatever;
//code below removed...

我设法插入了行"使用mylibrary.whatever"通过以下方式使用install.ps1(根据Nuget包约定),尽管不是那么复杂(对PowerShell很少有经验):

  

Blockquote 1:
  $ p = get-project;
  $ p =拆分路径$ p.filename;
  $ p + =" \ App_Start \ NinjectWebCommon.cs";
  (Get-Content $ p)| foreach-object {$ _ -replace"使用Ninject.Web.Common;","使用Ninject.Web.Common;`r`n使用mylibrary.whatever;"} | Set-Content $ p;

现在对于1行添加非常好。

我的问题在于更改此部分......

// code above removed...
private static void RegisterServices(IKernel kernel)
{
}
// code below removed...

到此......

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
}
// code below removed...

为了使事情更复杂一点,这个NinjectWebCommon.cs文件可以通过x个内部Nuger包以相同的方式更改。所以

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
}
// code below removed...

也可能成为

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
    kernel.Load(new myotherlibrarymodule());
    kernel.Load(new anotherlibrarymodule());
}
// code below removed...

任何帮助都会受到赞赏,因为powershell不是我的优点之一......

3 个答案:

答案 0 :(得分:2)

管理最终在我的install.ps1中使用大量的T& E对其进行排序:

  我的Nuget包中的

install.ps1

#Get the file:
$p = get-project;
$p = Split-path $p.filename;
$p += "\App_Start\NinjectWebCommon.cs";

# Do the first insert
$regex = new-object Text.RegularExpressions.Regex "using Ninject.Web.Common;", ('singleline');

set-content $p $regex.Replace((get-content $p) -join "`n", "using Ninject.Web.Common;`n`tusing mylibrary.whatever;")

# Do second insert
$regex = new-object Text.RegularExpressions.Regex "private static void RegisterServices\(IKernel kernel\)\s*\{", ('singleline','multiline');

set-content $p $regex.Replace((get-content $p) -join "`n", "private static void RegisterServices(IKernel kernel)`n`t`t{`n`t`t`tkernel.Load(new myclass_in_mylibrary.whatever());")

信用:

马特沃德回答here
Stej回答here

下一个挑战是在文件被编辑后允许完全卸载文件,因为如果文件被修改,Nuget不允许卸载... *叹息......

答案 1 :(得分:0)

我对ps也很陌生,不得不做一些搜索和测试来得出这个:

$fileName="C:\tmp\YourFileName"
$searchString="Primary search string here" #In your case it's: "private static void RegisterServices(IKernel kernel)"
$searchStrFound=0

(Get-Content $fileName) | 
Foreach-Object {
    #Send each line to output
    $_
    if ($_ -match $searchString)
    {
        #We found the actual search string
        $searchStrFound=1
    }
    if ($searchStrFound=1 -And $_ -match "\{")
    #If search string is already found and current line is {
    {
        "Insert your text here"
        "Insert Line 2 here"
        "Insert whatever here..."
        $searchStrFound=0 #Reset value to 0 so that you won't change anything else
    }
} | Set-Content $fileName

我用你的

尝试了这个
// code above removed...
private static void RegisterServices(IKernel kernel)
{
}
// code below removed...

示例,它运作得很好。

我希望它有所帮助

/ UT

答案 2 :(得分:0)

我实际上会推荐相反的方法:不要覆盖该文件,创建自己的MyNinjectBindings并通过自述文件指示开发人员手动将调用添加到您的代码中,以便注册您的绑定。

这样,如果更新了包,MyNinjectBindings也会更新,但开发人员可能已添加到NinjectWebCommon.cs的自定义代码仍然存在。

这是一种不那么具有侵入性的方式,而且更灵活,我的意见。

由于