Metin Dosyalarını Okumak ve Metni Değiştirmek için PowerShell'i Kullanma
Bir metin dosyasını okumak ve metni değiştirmek için PowerShell'i nasıl kullanacağınızı bilmeniz mi gerekiyor? Buna PowerShell Okuma Metni Dosyası diyoruz.
Başka yerde arama! Bu blog yazısı sizin için. Yazının sonunda size hayatınızı çok daha kolaylaştırmak için oluşturduğum bir işlevi göstereceğim.
Bir dosyadaki metni PowerShell ile değiştirmek üç adımlı bir işlemdir.
- Dosyayı okuma
- Dizeyi bulma ve değiştirme
- Dosyadaki değişiklikleri yazma.
Dosyayı Okumak
Öncelikle dosyayı okumanız gerekecek. Öncelikle Set-Content cmdlet'iyle bir tane oluşturalım, böylece üzerinde çalışabileceğimiz bir tane olsun.
Set-Content -Path 'C:\file.txt' -Value 'foo bar baz'Bu dosyayı okumak için Get-Content komutunu kullanabilirsiniz. Aşağıda gösterildiği gibi Path parametresine bir metin dosyası yolu sağlayarak dosyayı okuyabilirsiniz.
$content = Get-Content -Path 'C:\file.txt'Dizeyi Bulma ve Değiştirme
Artık dosyanın içeriğini bir dizede belleğe aldığımıza göre, dizeyi arayıp değiştirmemiz gerekiyor. Bunu yapmanın bir yolu -replace operatörünü kullanmaktır. Bu PowerShell operatörü bir dize bulur ve onu başka bir dizeyle değiştirir.
Örnek dosya içeriğini kullanarak, foo arama dizesine, dosya içeriğini şimdi foo foo baz yapacak olan bar değiştirme dizesini sağlayabiliriz.
PS> $newContent = $content -replace 'foo', 'bar'
bar bar bazDosyaya Yazma
Artık yeni dosya içeriklerini $newContent dosyasına kaydettiğimize göre, bu yeni içeriği tekrar dosyaya yazmamız gerekebilir. Bunu yapmanın bir yolu Set-Content komutunu kullanmaktır.
Set-Content komutu, bir dosyanın tüm içeriğini yeni bir değer atayarak değiştirir.
$newContent | Set-Content -Path 'C:\file.txt'Artık C:\file.txt dosyasını Get-Content ile okuduğunuzda, dosyanın artık yeni içeriği içerdiğini göreceksiniz.
Açık Dosya Tanıtıcılarıyla Başa Çıkmak
Daha önce uyguladığınız adımlar çoğu zaman işe yarar. Ancak gerçek dünyada her şeyin her zaman bu şekilde sonuçlanmadığını göreceksiniz.
Bazen PowerShell'in kendisi açık olan dosyalarla uğraşmak zorunda kalacağınızı göreceksiniz. Bu, yeni içerikleri dosyaya geri yazmanızı engeller.
Bu açık dosya işleme durumunu düzeltmek için, önce diskte yeni içeriklerle geçici bir metin dosyası oluşturmanıza, orijinal dosyayı kaldırmanıza ve ardından geçici dosyayı yeniden adlandırmanıza olanak tanıyan basit bir iş akışı oluşturdum.
İşte nasıl çalıştığına dair bir örnek:
$filePath = 'C:\file.txt'
$tempFilePath = "$env:TEMP\$($filePath | Split-Path -Leaf)"
$find = 'foo'
$replace = 'bar'
(Get-Content -Path $filePath) -replace $find, $replace | Add-Content -Path $tempFilePath
Remove-Item -Path $filePath
Move-Item -Path $tempFilePath -Destination $filePathAşağıda, bu yaklaşımı bir dosyadaki metni bulma (değiştirmeme) yeteneğiyle birlikte kullanan, Find-InTextFile adlı benim oluşturduğum bir fonksiyonun örneği verilmiştir.
Bu işlev aynı zamanda dizeleri bulmak için daha güçlü düzenli ifade sözdizimini de kullanır. Düzenli ifadelerin, tek tırnak işaretleri, özel karakterler ve daha fazlası gibi özel karakterleri kullanarak daha esnek arama yapmanıza olanak sağladığını göreceksiniz.
Aşağıda aynı anda birden fazla dosyayı işlemek için foreach döngüsü kullandığımı da görebilirsiniz. İşlenecek bir sürü dosyanız varsa bu kullanışlı olur.
function Find-InTextFile {
<#
.SYNOPSIS
Performs a find (or replace) on a string in a text file or files.
.EXAMPLE
PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
Replaces all instances of the string 'water' into the string 'wine' in
'C:\MyFile.txt'.
.EXAMPLE
PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water'
Finds all instances of the string 'water' in the file 'C:\MyFile.txt'.
.PARAMETER FilePath
The file path of the text file you'd like to perform a find/replace on.
.PARAMETER Find
The string you'd like to replace.
.PARAMETER Replace
The string you'd like to replace your 'Find' string with.
.PARAMETER NewFilePath
If a new file with the replaced the string needs to be created instead of replacing
the contents of the existing file use this param to create a new file.
.PARAMETER Force
If the NewFilePath param is used using this param will overwrite any file that
exists in NewFilePath.
#>
[CmdletBinding(DefaultParameterSetName = 'NewFile')]
[OutputType()]
param (
[Parameter(Mandatory = $true)]
[ValidateScript({Test-Path -Path $_ -PathType 'Leaf'})]
[string[]]$FilePath,
[Parameter(Mandatory = $true)]
[string]$Find,
[Parameter()]
[string]$Replace,
[Parameter(ParameterSetName = 'NewFile')]
[ValidateScript({ Test-Path -Path ($_ | Split-Path -Parent) -PathType 'Container' })]
[string]$NewFilePath,
[Parameter(ParameterSetName = 'NewFile')]
[switch]$Force
)
begin {
$Find = [regex]::Escape($Find)
}
process {
try {
foreach ($File in $FilePath) {
if ($Replace) {
if ($NewFilePath) {
if ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and $Force.IsPresent) {
Remove-Item -Path $NewFilePath -Force
(Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force
} elseif ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and !$Force.IsPresent) {
Write-Warning "The file at '$NewFilePath' already exists and the -Force param was not used"
} else {
(Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force
}
} else {
(Get-Content $File) -replace $Find, $Replace | Add-Content -Path "$File.tmp" -Force
Remove-Item -Path $File
Move-Item -Path "$File.tmp" -Destination $File
}
} else {
Select-String -Path $File -Pattern $Find
}
}
} catch {
Write-Error $_.Exception.Message
}
}
}Kaynaklar
Set-Content komutu hakkında daha fazla bilgi için Set-Content: Bir Dosyaya Yazmanın PowerShell Yolu'na veya bir dosyaya içerik yazmanın alternatif bir yoluna göz atın: Dosyadan Çıkar komutu.