Menggunakan PowerShell, saya ingin mengganti semua kemunculan yang tepat [MYID]
dalam file yang diberikan dengan MyValue
. Apa cara termudah untuk melakukannya?
powershell
amatir
sumber
sumber
Jawaban:
Gunakan (versi V3):
Atau untuk V2:
sumber
Perhatikan bahwa tanda kurung
(Get-Content file.txt)
diperlukan:sumber
Set-Content
alih-Out-File
alih Anda mendapatkan peringatan seperti "Proses tidak dapat mengakses file '123.csv' karena sedang digunakan oleh proses lain." .Get-Content
dalam tanda kurung berfungsi. Bisakah Anda menjelaskan dalam jawaban Anda mengapa tanda kurung diperlukan? Saya masih akan menggantiOut-File
denganSet-Content
karena lebih aman; itu melindungi Anda dari memusnahkan file target jika Anda lupa tanda kurung.Set-Content
bukanOut-File
solusi yang jauh lebih baik dan lebih aman. Maaf harus downvote.Saya lebih suka menggunakan File-class .NET dan metode statisnya seperti yang terlihat pada contoh berikut.
Ini memiliki keuntungan bekerja dengan String tunggal daripada String-array seperti dengan Get-Content . Metode ini juga menangani penyandian file (UTF-8 BOM , dll.) Tanpa Anda harus mengurus sebagian besar waktu.
Juga metode tidak mengacaukan akhir baris (akhir baris Unix yang mungkin digunakan) berbeda dengan algoritma menggunakan Get-Content dan pipa melalui Set-Content .
Jadi bagi saya: Lebih sedikit hal yang bisa pecah selama bertahun-tahun.
Suatu hal yang sedikit diketahui ketika menggunakan kelas .NET adalah bahwa ketika Anda telah mengetik "[System.IO.File] ::" di jendela PowerShell Anda dapat menekan Tabtombol untuk melangkah melalui metode di sana.
sumber
[System.IO.File] | gm
C:\Windows\System32\WindowsPowerShell\v1.0
?Yang di atas hanya berjalan untuk "Satu File" saja, tetapi Anda juga dapat menjalankan ini untuk beberapa file dalam folder Anda:
sumber
foreach
Anda dapat melakukan iniGet-ChildItem 'C:\folder\file*.xml' -Recurse | ForEach { (Get-Content $_).Replace('[MYID]', 'MyValue') | Set-Content $_ }
foreach
, karena Get-Content melakukan sesuatu yang mungkin tidak Anda harapkan ... Ini mengembalikan array string, di mana setiap string adalah sebuah baris dalam file. Jika Anda mengulang-ulang direktori (dan sub-direktori) yang berada di lokasi yang berbeda dari skrip Anda yang sedang berjalan, Anda akan menginginkan sesuatu seperti ini: diGet-ChildItem $Directory -File -Recurse | ForEach { (Get-Content $_.FullName) | ForEach { $_ -replace '[MYID]', 'MyValue' } | Set-Content $_.FullName }
mana$Directory
direktori berisi file yang ingin Anda modifikasi.Anda dapat mencoba sesuatu seperti ini:
sumber
Ini yang saya gunakan, tetapi lambat pada file teks besar.
Jika Anda akan mengganti string dalam file teks besar dan kecepatan adalah masalah, lihat menggunakan System.IO.StreamReader dan System.IO.StreamWriter .
(Kode di atas belum diuji.)
Mungkin ada cara yang lebih elegan untuk menggunakan StreamReader dan StreamWriter untuk mengganti teks dalam dokumen, tetapi itu akan memberi Anda titik awal yang baik.
sumber
Saya menemukan cara yang dikenal tetapi sangat keren untuk melakukannya dari Payette Windows Powershell in Action . Anda dapat mereferensikan file seperti variabel, mirip dengan $ env: path, tetapi Anda perlu menambahkan kurung kurawal.
sumber
$myFile
?$a = 'file.txt'; invoke-expression "`${c:$a} = `${c:$a} -replace 'oldvalue','newvalue'"
Jika Anda Perlu Mengganti String di Banyak File:
Perlu dicatat bahwa berbagai metode yang diposting di sini dapat sangat berbeda berkaitan dengan waktu yang diperlukan untuk menyelesaikannya. Bagi saya, saya secara teratur memiliki banyak file kecil. Untuk menguji apa yang paling performan, saya mengekstraksi XML 5,52 GB (5,933,604,999 bytes) dalam 40.693 file terpisah dan menjalankan tiga jawaban yang saya temukan di sini:
sumber
Kredit ke @ rominator007
Saya membungkusnya menjadi fungsi (karena Anda mungkin ingin menggunakannya lagi)
CATATAN: Ini BUKAN case sensitive !!!!!
Lihat posting ini: String.Replace case ignoring
sumber
Ini berhasil bagi saya menggunakan direktori kerja saat ini di PowerShell. Anda perlu menggunakan
FullName
properti, atau tidak akan berfungsi di PowerShell versi 5. Saya perlu mengubah versi .NET framework framework di SEMUACSPROJ
file saya .sumber
Agak lama dan berbeda, karena saya perlu mengubah baris tertentu dalam semua contoh nama file tertentu.
Juga,
Set-Content
tidak mengembalikan hasil yang konsisten, jadi saya harus menggunakanOut-File
.Kode di bawah ini:
Inilah yang paling cocok untuk saya di versi PowerShell ini:
sumber
Koreksi kecil untuk perintah Set-Content. Jika string yang dicari tidak ditemukan,
Set-Content
perintah akan mengosongkan (mengosongkan) file target.Pertama-tama Anda dapat memverifikasi apakah string yang Anda cari ada atau tidak. Jika tidak, itu tidak akan menggantikan apa pun.
sumber
set-content test.txt "hello hello world hello world hello"
dan kemudian(get-content .\test.txt).Replace("something", "awesome") | set-content .\test.txt
tidak akan mengosongkan file seperti yang disarankan dalam ini.