특정 확장자를 가진 모든 파일을 검색하여 교체하는 PowerShell 스크립트
다음과 같이 중첩된 구성 파일이 몇 개 있습니다.
C:\Projects\Project_1\project1.config
C:\Projects\Project_2\project2.config
설정에서는 다음과 같은 문자열 치환을 수행해야 합니다.
<add key="Environment" value="Dev"/>
다음과 같이 됩니다.
<add key="Environment" value="Demo"/>
배치 스크립트를 사용할까 생각했지만 좋은 방법이 없어서 PowerShell 스크립트를 사용하면 쉽게 실행할 수 있다고 들었습니다.find/replace의 예를 찾았습니다만, C:\Projects 디렉토리내의 모든 폴더를 이동해, 확장자 「.config」로 끝나는 파일을 찾을 수 있는 방법을 찾고 있었습니다.검색 시 문자열 값을 대체해 주었으면 합니다.
이 작업을 수행하는 방법을 알아보는 데 도움이 되는 리소스나 PowerShell 전문가가 있습니까?
여기 내 머리 꼭대기에서의 첫 번째 시도가 있다.
$configFiles = Get-ChildItem . *.config -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "Dev", "Demo" } |
Set-Content $file.PSPath
}
PowerShell을 선택하는 것이 좋습니다.) 지정된 디렉토리의 파일을 열거하고 읽고 처리하는 것은 매우 간단합니다.
스크립트는 다음과 같습니다.
Get-ChildItem C:\Projects *.config -recurse |
Foreach-Object {
$c = ($_ | Get-Content)
$c = $c -replace '<add key="Environment" value="Dev"/>','<add key="Environment" value="Demo"/>'
[IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
}
당신이 읽을 수 있도록 코드를 더 많은 행으로 분할했습니다.SET-Content를 사용하는 대신[IO.File]::WriteAllText
단, 마지막에 새로운 행이 추가됩니다.와 함께WriteAllText
피할 수 있어요.
그렇지 않으면 코드는 다음과 같습니다.$c | Set-Content $_.FullName
.
이 접근방식은 잘 기능합니다.
gci C:\Projects *.config -recurse | ForEach {
(Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_
}
- "old" 및 "new"를 대응하는 값으로 변경합니다(또는 변수 사용).
- 괄호도 잊지 마십시오. 괄호가 없으면 접근 오류가 발생합니다.
이 powershell 예에서는 폴더와 그 서브폴더에서 문자열 "\foo"의 모든 인스턴스를 찾고 "\foo"를 "\bar"로 대체하며 문자열 "\foo"를 포함하지 않는 파일을 다시 쓰지 않습니다.이 방법에서는 문자열을 찾을 수 없었던 마지막 업데이트 날짜 스탬프를 파기하지 않습니다.
Get-ChildItem -Path C:\YOUR_ROOT_PATH\*.* -recurse
| ForEach {If (Get-Content $_.FullName | Select-String -Pattern '\\foo\\')
{(Get-Content $_ | ForEach {$_ -replace '\\foo\\', '\bar\'}) | Set-Content $_ }
}
xml과 xpath를 사용합니다.
dir C:\Projects\project_*\project*.config -recurse | foreach-object{
$wc = [xml](Get-Content $_.fullname)
$wc.SelectNodes("//add[@key='Environment'][@value='Dev']") | Foreach-Object {$_.value = 'Demo'}
$wc.Save($_.fullname)
}
@Artyom님의 코멘트는 도움이 되었습니다만, 유감스럽게도 답변으로 게재되지 않았습니다.
내 생각에 이것은 받아들여진 대답의 짧은 버전이다.
ls *.config -rec | %{$f=$_; (gc $f.PSPath) | %{$_ -replace "Dev", "Demo"} | sc $f.PSPath}
파일의 텍스트를 대체하는 작은 도우미 기능을 작성했습니다.
function Replace-TextInFile
{
Param(
[string]$FilePath,
[string]$Pattern,
[string]$Replacement
)
[System.IO.File]::WriteAllText(
$FilePath,
([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
)
}
예:
Get-ChildItem . *.config -rec | ForEach-Object {
Replace-TextInFile -FilePath $_ -Pattern 'old' -Replacement 'new'
}
재귀 치환을 수행할 때는 경로와 파일 이름을 포함해야 합니다.
Get-ChildItem -Recurse | ForEach { (Get-Content $_.PSPath |
ForEach {$ -creplace "old", "new"}) | Set-Content $_.PSPath }
현재 디렉토리의 모든 폴더 파일에서 "이전"을 대소문자를 구분하는 "새"로 바꿉니다.
언급URL : https://stackoverflow.com/questions/2837785/powershell-script-to-find-and-replace-for-all-files-with-a-specific-extension
'IT' 카테고리의 다른 글
C# 프로그램을 50밀리초 동안 sleep 상태로 만들려면 어떻게 해야 하나요? (0) | 2023.04.08 |
---|---|
'<' 연산자는 향후 사용을 위해 예약되어 있습니다. (0) | 2023.04.08 |
NVARCHAR(MAX)의 최대 문자는 얼마입니까? (0) | 2023.04.08 |
명령줄에서 스크립트를 실행하는 '보안 경고' 무시 (0) | 2023.04.08 |
Invoke-WebRequest 진행률 숨기기 (0) | 2023.04.08 |