2016-08-23 2 views
3

У меня есть следующий сценарий:Объединить файл IO для -replace и Set-Content в PowerShell

$allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")} 
foreach($file in $allFiles) 
{ 
    # Find and replace the dash cased the contents of the files 
    (Get-Content $file.PSPath) | 
     Foreach-Object {$_ -replace "my-project-name", '$appNameDashCased$'} | 
     Set-Content $file.PSPath  

    # Find and replace the dash cased the contents of the files 
    (Get-Content $file.PSPath) | 
     Foreach-Object {$_ -replace "MyProjectName", '$appNameCamelCased$'} | 
     Set-Content $file.PSPath  

    # Find and replace the dash cased the contents of the files 
    (Get-Content $file.PSPath) | 
     Foreach-Object {$_ -replace "myProjectName", '$appNamePascalCased$'} | 
     Set-Content $file.PSPath  
} 

Он принимает файл и делает некоторые замены, а затем сохраняет файл. Затем он принимает тот же файл и выполняет некоторую замену, а затем сохраняет файл снова. Затем он делает это еще раз.

Это работает, но кажется неэффективным.

Есть ли способ сделать все замену, а затем сохранить файл один раз?

(Если это возможно, я бы предпочел, чтобы сохранить читаемый стиль PowerShell.)

+0

Ответ от TheMadTechnician получил мой голос. Другие вещи, когда я вижу ваш код: Первая строка неуклюжая: '. /' Is Linux for 'here', поэтому оставьте это, Get-ChildItem предполагает текущий путь (и текущий диск PS), если вы не укажете один , Трубопровод вывода в «Где-Объект» работает, но в этой команде он неэффективен, поскольку команда имеет встроенную фильтрацию. Кроме того, с предложением where-object, которое вы использовали, у вас есть фигурные скобки вокруг круглых скобок. Скобки не требуются. '$ allFiles = Get-ChildItem -recurse -Include" * .ts "'. Для Get-Content вы можете просто использовать объект $ file. 'Get-Content $ file' – Xalorous

ответ

2

Конечно, только цепь ваши Заменяет внутри ForEach-Object блока:

$allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")} 
foreach($file in $allFiles) 
{ 
    (Get-Content $file.PSPath) | 
     Foreach-Object { 
      # Find and replace the dash cased the contents of the files 
      $_ -replace "my-project-name", '$appNameDashCased$' ` 
       -replace "MyProjectName", '$appNameCamelCased$' ` 
       -replace "myProjectName", '$appNamePascalCased$' 
     } | 
     Set-Content $file.PSPath  
} 
+0

@Xalorous Я не слежу .. не могли бы вы рассказать о том, что вы имеете в виду? Я не думаю, что нужны дополнительные трубы. – briantist

+0

Я удалил свой комментарий, когда он погрузился в то, что это была одна длинная команда. Тем не менее, ваш код не имеет ничего, поддерживающего линию, идущую в конце строк «-replace», я не уверен, что следующая строка начинается с -replace. Я думаю, что вам нужна обратная связь в конце первых двух. – Xalorous

+0

@Xalorous true, исправлено, спасибо! – briantist

3

Это может быть сделано, и на самом деле намного проще, чем вы делаете. Вы можете связать команду -Replace как таковую:

$allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")} 
foreach($file in $allFiles) 
{ 
    # Find and replace the dash cased the contents of the files 
    (Get-Content $file.PSPath) -replace "my-project-name", '$appNameDashCased$' -replace "StringB", '$SecondReplacement$' -replace "StringC", '$ThirdReplacement$' | Set-Content $file.PSPath 
} 
+0

Ницца! Я думаю, что «Set-Content» может потерпеть неудачу таким образом из-за конвейера, следовательно, его завершение «Get-Content» в круглых скобках приведет к тому, что весь файл будет считаться первым, но это также можно легко применить к этому. – briantist

+0

Я не думаю, что это совместимо с PowerShell 2.0 .... – Vaccano

+0

Я тоже пробовал это в PowerShell 4.0, и он не работает там ни .... Жаловался на то, что не знал, что такое замена. – Vaccano