IT

파일에서 모든 문자열을 PowerShell로 바꾸려면 어떻게해야합니까?

lottoking 2020. 3. 29. 09:15
반응형

파일에서 모든 문자열을 PowerShell로 바꾸려면 어떻게해야합니까?


PowerShell을 사용 [MYID]하여 주어진 파일에서 발생하는 모든 정확한 항목을로 바꾸고 싶습니다 MyValue. 가장 쉬운 방법은 무엇입니까?


사용 (V3 버전) :

(Get-Content c:\temp\test.txt).replace('[MYID]', 'MyValue') | Set-Content c:\temp\test.txt

또는 V2의 경우 :

(Get-Content c:\temp\test.txt) -replace '\[MYID\]', 'MyValue' | Set-Content c:\temp\test.txt

(Get-Content file.txt) | 
Foreach-Object {$_ -replace '\[MYID\]','MyValue'}  | 
Out-File file.txt

괄호 (Get-Content file.txt)는 다음과 같습니다.

괄호가 없으면 내용이 한 번에 한 줄씩 읽혀지고 파일 또는 세트 내용에 도달 할 때까지 파이프 라인을 따라 내려갑니다. 동일한 파일에 쓰려고 시도하지만 get-content에 의해 이미 열려 있고 오류. 괄호로 인해 콘텐츠 읽기 작업이 한 번만 수행됩니다 (열기, 읽기 및 닫기). 그런 다음에 만 모든 행을 읽을 때 한 번에 하나씩 파이프되고 파이프 라인의 마지막 명령에 도달하면 파일에 쓸 수 있습니다. $ content = content와 동일합니다. $ content | 어디 ...


다음 예제에서 볼 수 있듯이 File 클래스의 .NET과 정적 메서드를 사용하는 것이 좋습니다.

$content = [System.IO.File]::ReadAllText("c:\bla.txt").Replace("[MYID]","MyValue")
[System.IO.File]::WriteAllText("c:\bla.txt", $content)

이것은 Get-Content 와 같이 String-array 대신 단일 String으로 작업 할 수 있다는 이점이 있습니다 . 또한이 방법은 대부분의 시간을 돌보지 않고도 파일 인코딩 (UTF-8 BOM 등)을 처리합니다.

또한 메소드는 Get-Content를 사용하고 Set-Content로 파이프하는 알고리즘과 달리 줄 끝 (사용할 수있는 Unix 줄 끝)을 엉망으로 만들지 않습니다 .

그래서 나를 위해 : 몇 년 동안 깰 수있는 것들이 적습니다.

.NET 클래스를 사용할 때 잘 알려진 점은 PowerShell 창에서 "[System.IO.File] ::"을 입력하면 Tab키를 눌러 방법을 단계별로 진행할 수 있다는 것입니다.


위의 파일은 "하나의 파일"에 대해서만 실행되지만 폴더 내의 여러 파일에 대해서도 실행할 수 있습니다.

Get-ChildItem 'C:yourfile*.xml' -Recurse | ForEach {
     (Get-Content $_ | ForEach  { $_ -replace '[MYID]', 'MyValue' }) |
     Set-Content $_
}

다음과 같이 시도해보십시오.

$path = "C:\testFile.txt"
$word = "searchword"
$replacement = "ReplacementText"
$text = get-content $path 
$newText = $text -replace $word,$replacement
$newText > $path

이것이 내가 사용하는 것이지만 큰 텍스트 파일에서는 느립니다.

get-content $pathToFile | % { $_ -replace $stringToReplace, $replaceWith } | set-content $pathToFile

큰 텍스트 파일에서 문자열을 바꾸고 속도가 문제가되는 경우 System.IO.StreamReaderSystem.IO.StreamWriter 사용을 살펴보십시오 .

try
{
   $reader = [System.IO.StreamReader] $pathToFile
   $data = $reader.ReadToEnd()
   $reader.close()
}
finally
{
   if ($reader -ne $null)
   {
       $reader.dispose()
   }
}

$data = $data -replace $stringToReplace, $replaceWith

try
{
   $writer = [System.IO.StreamWriter] $pathToFile
   $writer.write($data)
   $writer.close()
}
finally
{
   if ($writer -ne $null)
   {
       $writer.dispose()
   }
}

(위의 코드는 테스트되지 않았습니다.)

문서에서 텍스트를 바꾸는 데 StreamReader와 StreamWriter를 사용하는 더 우아한 방법이있을 수 있지만 좋은 출발점이 될 것입니다.


@ rominator007에 신용

함수에 래핑했습니다 (다시 사용하고 싶을 수도 있기 때문에)

function Replace-AllStringsInFile($SearchString,$ReplaceString,$FullPathToFile)
{
    $content = [System.IO.File]::ReadAllText("$FullPathToFile").Replace("$SearchString","$ReplaceString")
    [System.IO.File]::WriteAllText("$FullPathToFile", $content)
}

참고 : 이것은 대소 문자를 구분하지 않습니다 !!!!!

이 게시물을 참조하십시오 : String. 대소 문자를 무시 하십시오.


Payette의 Windows Powershell in Action 에서 조금 알려졌지만 놀랍도록 멋진 방법을 찾았습니다 . $ env : path와 비슷한 변수와 같은 파일을 참조 할 수 있지만 중괄호를 추가해야합니다.

${c:file.txt} = ${c:file.txt} -replace 'oldvalue','newvalue'

이것은 PowerShell에서 현재 작업 디렉토리를 사용하여 나를 위해 일했습니다. FullName속성 을 사용해야합니다. 그렇지 않으면 PowerShell 버전 5에서 작동하지 않습니다 CSPROJ. 모든 파일 에서 대상 .NET 프레임 워크 버전을 변경해야했습니다 .

gci -Recurse -Filter *.csproj |
% { (get-content "$($_.FullName)")
.Replace('<TargetFramework>net47</TargetFramework>', '<TargetFramework>net462</TargetFramework>') |
 Set-Content "$($_.FullName)"}

특정 파일 이름의 모든 인스턴스에서 특정 줄을 변경해야했기 때문에 조금 오래되었습니다.

또한 Set-Content일관된 결과를 반환하지 않았으므로에 의지해야했습니다 Out-File.

아래 코드 :


$FileName =''
$OldLine = ''
$NewLine = ''
$Drives = Get-PSDrive -PSProvider FileSystem
foreach ($Drive in $Drives) {
    Push-Location $Drive.Root
        Get-ChildItem -Filter "$FileName" -Recurse | ForEach { 
            (Get-Content $_.FullName).Replace($OldLine, $NewLine) | Out-File $_.FullName
        }
    Pop-Location
}

이것이이 PowerShell 버전에서 가장 효과적이었습니다.

주요 사소한 건물 개정

5.1.16299.98


Set-Content 명령에 대한 작은 수정. 검색된 문자열을 찾지 못하면 Set-Content명령은 대상 파일을 비 웁니다 (비어 있음).

찾고있는 문자열이 존재하는지 먼저 확인할 수 있습니다. 그렇지 않으면 아무것도 교체되지 않습니다.

If (select-string -path "c:\Windows\System32\drivers\etc\hosts" -pattern "String to look for") `
    {(Get-Content c:\Windows\System32\drivers\etc\hosts).replace('String to look for', 'String to replace with') | Set-Content c:\Windows\System32\drivers\etc\hosts}
    Else{"Nothing happened"}

참고 URL : https://stackoverflow.com/questions/17144355/how-can-i-replace-every-occurrence-of-a-string-in-a-file-with-powershell

반응형