代码之家  ›  专栏  ›  技术社区  ›  Stefan0309

更改.txt文件并用powershell保存

  •  0
  • Stefan0309  · 技术社区  · 5 年前

    我正在用powershell在一些.txt文件中执行经典的查找和替换。 如何在结尾处“保存”文件?我试过设置内容,但什么也没发生。 也许我需要先添加内容?

    #Find what?
    $optionBuilderStringToFind = "optionsBuilder.UseSqlServer"
    $findUsingKeywordString = "using Microsoft."
    
    #Replace with
    $namespaceAdd = "using Microsoft.Extensions.Configuration;"
    $optionBuilderConfigurable ="optionsBuilder.UseSqlServer(_configuration.GetConnectionString(`"Database`") 
     );"
    
    gc -Path .\APSContext.cs | % { 
    if ($_ -match "using System;") {
        $_ = $_ + "`n" + $namespaceAdd
        #write-host $_
    }
    if ($_ -match "optionsBuilder.UseSqlServer") {
        $_ = $optionBuilderConfigurable
        #write-host $_
    }
    } | Set-Content -Path .\test.cs
    

    更新:这是一个测试文件,我正在修改它。文件的内容并不重要。我想添加另一个引用,比如“using something.something”,并在文件中间替换 "optionsBuilder.UseSqlServer("dfjidfjljfiejf88");" 具有 "optionsBuilder.UseSqlServer("_configtest");" :

    using System;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    
    namespace SRC.APS.Model.APSDB
    {
    public partial class APSContext : DbContext
    {
        public APSContext()
        {
        }
    
        public APSContext(DbContextOptions<APSContext> options)
            : base(options)
           protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
    
                optionsBuilder.UseSqlServer("dfjidfjljfiejf88");
            }
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
    
        }
    

    也许我需要用绳子代替?

    2 回复  |  直到 5 年前
        1
  •  1
  •   Tomalak    5 年前

    powershell中的任何脚本块都可以生成值。这是由 在变量中存储值:

    • { $foo = 3 } 一无所获
    • { 3 } 产生整数 3 .

    以同样的方式

    • ForEach-Object { $_ = "something" } 一无所获
    • ForEach-Object { $_ = "something"; $_ } 生成字符串 "something"

    循环体不输出任何内容,就像上面的示例一样。因此, Set-Content 无事可做。修改块以实际返回 $_ :

    $replacements = @(
        @{regex='using (System|Potentially|Others);'; replacement='using Microsoft.$1;' }
        @{regex='optionsBuilder\.UseSqlServer\("[^"]*"\)'; replacement='optionsBuilder.UseSqlServer("Database")' }
        # more search/replace pairs
    )
    
    Get-Content .\APSContext.cs -Encoding UTF8 | ForEach-Object {
        foreach ($item in $replacements) {
            $_ = $_ -replace $item.regex, $item.replacement
        }
        $_   # <--- this is what produces the line
    } | Set-Content -Path .\test.cs -Encoding UTF8
    

    也就是说,不要加载或保存没有指定编码的文本文件。对于c源代码文件,我认为utf-8是默认的。

    那个 也就是说,用正则表达式修改源代码不是一件好事。如果这是一次性的,可以。如果你打算定期这样做,那你就做错了。使用配置文件或环境变量,而不是保存在代码基文本值中,这些值会定期更改。

        2
  •  0
  •   Lee_Dailey    5 年前

    正如我所提到的——正如托马拉克所指出的——你对当前管道对象的干扰是问题的根源。[ 露齿而笑 ]这段代码修复了if cascade中的一个逻辑错误[使用 switch 阻止],消除不明智 $_ 摆弄,然后确保总是有一些输出。

    # fake reading in a text file
    #    in real life, use Get-Content
    $InStuff = @'
    using System;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    
    namespace SRC.APS.Model.APSDB
    {
    public partial class APSContext : DbContext
    {
        public APSContext()
        {
        }
    
        public APSContext(DbContextOptions<APSContext> options)
            : base(options)
           protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
    
                optionsBuilder.UseSqlServer("dfjidfjljfiejf88");
            }
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
    
        }
    '@ -split [environment]::NewLine
    
    #Find what?
    $optionBuilderStringToFind = "optionsBuilder.UseSqlServer"
    $findUsingKeywordString = "using Microsoft."
    
    #Replace with
    $namespaceAdd = 'using Microsoft.Extensions.Configuration;'
    $optionBuilderConfigurable ='optionsBuilder.UseSqlServer(_configuration.GetConnectionString("Database"));'
    
    $InStuff | ForEach-Object { 
        if ($_ -match "using System;")
            {
            $_ + "`n" + $namespaceAdd
            #write-host $_
            }
            elseif ($_ -match "optionsBuilder.UseSqlServer")
            {
            $optionBuilderConfigurable
            #write-host $_
            }
            else
            {
            $_
            }
        }
    

    输出…

    using System;
    using Microsoft.Extensions.Configuration;
    using Microsoft.EntityFrameworkCore;
    using Microsoft.EntityFrameworkCore.Metadata;
    
    namespace SRC.APS.Model.APSDB
    {
    public partial class APSContext : DbContext
    {
        public APSContext()
        {
        }
    
        public APSContext(DbContextOptions<APSContext> options)
            : base(options)
           protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
    
    optionsBuilder.UseSqlServer(_configuration.GetConnectionString("Database"));
            }
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
    
        }