изменить файл .txt и сохранить его с помощью PowerShell - PullRequest
0 голосов
/ 14 января 2019

Я делаю классический поиск и замену в некотором .txt файле с powershell. Как я могу "сохранить" файл в конце? Я пытался с | Set-Content, но ничего не происходит. Может быть, мне сначала нужно добавить контент?

#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

Обновление: вот testFile, где я хочу изменить его. Содержание файла не важно. Я хочу добавить еще одну ссылку, например «используя 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");

    }

Может мне вместо этого использовать Out-String?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Любой блок скриптов в 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.

И , что, как говорится, 1033 *, изменение исходного кода с помощью регулярных выражений не очень хорошая вещь. Если это разовое, хорошо. Если вы планируете делать это регулярно, вы делаете что-то не так. Работайте с файлами конфигурации или переменными среды, вместо того чтобы хранить в своем коде буквальные значения, которые могут регулярно изменяться.

0 голосов
/ 14 января 2019

, как я уже упоминал - и, как указал Томалак, - ваша ошибка с текущим объектом конвейера является источником сбоя. [ ухмылка ] этот код исправляет логическую ошибку в вашем каскаде ПЧ [что может быть лучше сделано с блоком 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");

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...