Dalam jawaban di bawah ini, ketahuilah bahwa setiap rekomendasi untuk digunakan File.readperlu disesuaikan dengan informasi di stackoverflow.com/a/25189286/128421 untuk mengapa menyeruput file besar itu buruk. Juga, alih-alih File.open(filename, "w") { |file| file << content }menggunakan variasi File.write(filename, content).
Tin Man
Jawaban:
190
Penafian: Pendekatan ini adalah ilustrasi naif dari kemampuan Ruby, dan bukan solusi tingkat produksi untuk mengganti string dalam file. Ini rentan terhadap berbagai skenario kegagalan, seperti kehilangan data jika terjadi crash, interupsi, atau disk penuh. Kode ini tidak cocok untuk apa pun selain skrip cepat satu kali yang semua datanya dicadangkan. Oleh karena itu, JANGAN menyalin kode ini ke dalam program Anda.
Berikut cara singkat dan cepat untuk melakukannya.
file_names =['foo.txt','bar.txt']
file_names.each do|file_name|
text =File.read(file_name)
new_contents = text.gsub(/search_regexp/,"replacement string")# To merely print the contents of the file, use:
puts new_contents
# To write changes to the file, use:File.open(file_name,"w"){|file| file.puts new_contents }end
Apakah menempatkan menulis perubahan kembali ke file? Saya pikir itu hanya akan mencetak konten ke konsol.
Dane O'Connor
Ya, itu mencetak konten ke konsol.
sepp2k
7
Ya, saya tidak yakin itu yang Anda inginkan. Untuk menulis gunakan File.open (nama_file, "w") {| file | file.puts output_of_gsub}
Max Chernyak
7
Saya harus menggunakan file.write: File.open (nama_file, "w") {| file | file.write (teks)}
austen
3
Untuk menulis file, ganti put 'line denganFile.write(file_name, text.gsub(/regexp/, "replace")
ketat
106
Sebenarnya, Ruby memiliki fitur pengeditan di tempat. Seperti Perl, bisa dibilang
ruby -pi.bak -e "gsub(/oldtext/, 'newtext')"*.txt
Ini akan menerapkan kode dalam tanda kutip ganda ke semua file di direktori saat ini yang namanya diakhiri dengan ".txt". Salinan cadangan dari file yang diedit akan dibuat dengan ekstensi ".bak" ("foobar.txt.bak" menurut saya).
CATATAN: ini tampaknya tidak berfungsi untuk pencarian multiline. Untuk itu, Anda harus melakukannya dengan cara lain yang kurang cantik, dengan skrip pembungkus di sekitar regex.
Apa sih pi.bak itu? Tanpa itu, saya mendapatkan kesalahan. -e: 1: di <main>': undefined method gsub 'untuk main: Object (NoMethodError)
Ninad
15
@NinadPachpute -imengedit di tempat. .bakadalah ekstensi yang digunakan untuk file cadangan (opsional). -padalah sesuatu seperti while gets; <script>; puts $_; end. ( $_adalah baris baca terakhir, tetapi Anda dapat menetapkannya untuk sesuatu seperti echo aa | ruby -p -e '$_.upcase!'.)
Lri
1
Ini adalah jawaban yang lebih baik daripada jawaban yang diterima, IMHO, jika Anda ingin mengubah file.
Colin K
6
Bagaimana saya bisa menggunakan ini di dalam skrip ruby ??
Saurabh
1
Ada banyak hal yang bisa menyebabkan kesalahan ini, jadi ujilah secara menyeluruh sebelum mencobanya pada file penting.
the Tin Man
49
Ingatlah bahwa, ketika Anda melakukan ini, sistem file mungkin kehabisan ruang dan Anda dapat membuat file dengan panjang nol. Ini bencana jika Anda melakukan sesuatu seperti menulis file / etc / passwd sebagai bagian dari manajemen konfigurasi sistem.
Perhatikan bahwa pengeditan file di tempat seperti pada jawaban yang diterima akan selalu memotong file dan menulis file baru secara berurutan. Akan selalu ada kondisi balapan di mana pembaca yang bersamaan akan melihat file yang terpotong. Jika proses dibatalkan karena alasan apa pun (ctrl-c, OOM killer, system crash, power outage, dll) selama penulisan, maka file yang terpotong juga akan tertinggal, yang dapat menjadi bencana besar. Ini adalah jenis skenario dataloss yang HARUS dipertimbangkan oleh pengembang karena itu akan terjadi. Untuk alasan itu, saya pikir jawaban yang diterima kemungkinan besar bukan jawaban yang diterima. Minimal tulis ke tempfile dan pindahkan / ganti nama file ke tempatnya seperti solusi "sederhana" di akhir jawaban ini.
Anda perlu menggunakan algoritme yang:
Membaca file lama dan menulis ke file baru. (Anda harus berhati-hati saat memasukkan seluruh file ke dalam memori).
Menutup file sementara baru secara eksplisit, di mana Anda dapat melontarkan pengecualian karena buffer file tidak dapat ditulis ke disk karena tidak ada ruang. (Tangkap ini dan bersihkan file sementara jika Anda mau, tetapi Anda perlu mengembalikan sesuatu atau gagal cukup keras saat ini.
Memperbaiki izin dan mode file pada file baru.
Ubah nama file baru dan letakkan di tempatnya.
Dengan sistem file ext3 Anda dijamin bahwa penulisan metadata untuk memindahkan file ke tempatnya tidak akan diatur ulang oleh sistem file dan ditulis sebelum buffer data untuk file baru ditulis, jadi ini akan berhasil atau gagal. Sistem file ext4 juga telah ditambal untuk mendukung perilaku semacam ini. Jika Anda sangat paranoid, Anda harus memanggil panggilan fdatasync()sistem sebagai langkah 3.5 sebelum memindahkan file ke tempatnya.
Terlepas dari bahasanya, ini adalah praktik terbaik. Dalam bahasa di mana pemanggilan close()tidak memunculkan pengecualian (Perl atau C), Anda harus secara eksplisit memeriksa kembalinya close()dan melempar pengecualian jika gagal.
Saran di atas untuk hanya menghirup file ke dalam memori, memanipulasinya, dan menulisnya ke file akan dijamin menghasilkan file dengan panjang nol pada sistem file penuh. Anda harus selalu menggunakan FileUtils.mvuntuk memindahkan file sementara yang ditulis lengkap ke tempatnya.
Pertimbangan terakhir adalah penempatan file sementara. Jika Anda membuka file di / tmp maka Anda harus mempertimbangkan beberapa masalah:
Jika / tmp dipasang pada sistem file yang berbeda, Anda dapat menjalankan / tmp kehabisan ruang sebelum Anda menulis file yang seharusnya dapat diterapkan ke tujuan file lama.
Mungkin yang lebih penting, ketika Anda mencoba mvfile di perangkat mount Anda akan secara transparan diubah ke cpperilaku. File lama akan dibuka, inode file lama akan dipertahankan dan dibuka kembali dan konten file akan disalin. Ini kemungkinan besar bukan yang Anda inginkan, dan Anda mungkin mengalami kesalahan "file teks sibuk" jika Anda mencoba mengedit konten file yang sedang berjalan. Ini juga menggagalkan tujuan penggunaan mvperintah sistem berkas dan Anda dapat menjalankan sistem berkas tujuan di luar ruang dengan hanya berkas yang ditulis sebagian.
Ini juga tidak ada hubungannya dengan implementasi Ruby. Sistem mvdan cpperintah berperilaku serupa.
Apa yang lebih disukai adalah membuka Tempfile di direktori yang sama dengan file lama. Ini memastikan bahwa tidak akan ada masalah perpindahan lintas perangkat. Itu mvsendiri tidak akan pernah gagal, dan Anda harus selalu mendapatkan file yang lengkap dan tidak terpotong. Kegagalan apa pun, seperti perangkat kehabisan ruang, kesalahan izin, dll., Harus ditemui selama penulisan Tempfile.
Satu-satunya kelemahan pendekatan pembuatan Tempfile di direktori tujuan adalah:
Terkadang Anda mungkin tidak dapat membuka Tempfile di sana, seperti jika Anda mencoba 'mengedit' file di / proc misalnya. Oleh karena itu, Anda mungkin ingin mundur dan mencoba / tmp jika membuka file di direktori tujuan gagal.
Anda harus memiliki cukup ruang di partisi tujuan untuk menyimpan file lama dan file baru secara lengkap. Namun, jika Anda tidak memiliki cukup ruang untuk menyimpan kedua salinan maka Anda mungkin kekurangan ruang disk dan risiko sebenarnya dari menulis file yang terpotong jauh lebih tinggi, jadi saya berpendapat ini adalah pertukaran yang sangat buruk di luar beberapa yang sangat sempit (dan baik -Diawasi) kasus tepi.
Berikut beberapa kode yang menerapkan algoritme lengkap (kode windows belum teruji dan belum selesai):
Dan ini adalah versi yang sedikit lebih ketat yang tidak mengkhawatirkan setiap kemungkinan kasus tepi (jika Anda menggunakan Unix dan tidak peduli tentang menulis ke / proc):
Kasus penggunaan yang sangat sederhana, ketika Anda tidak peduli dengan izin sistem file (baik Anda tidak menjalankan sebagai root, atau Anda menjalankan sebagai root dan file tersebut dimiliki root):
TL; DR : Itu setidaknya harus digunakan sebagai ganti jawaban yang diterima, dalam semua kasus, untuk memastikan pembaruan bersifat atomic dan pembaca yang bersamaan tidak akan melihat file yang terpotong. Seperti yang saya sebutkan di atas, membuat Tempfile di direktori yang sama dengan file yang diedit penting di sini untuk menghindari operasi mv lintas perangkat diterjemahkan ke dalam operasi cp jika / tmp dipasang pada perangkat yang berbeda. Memanggil fdatasync adalah lapisan tambahan dari paranoia, tetapi akan menimbulkan performa yang buruk, jadi saya menghilangkannya dari contoh ini karena hal ini tidak umum dilakukan.
Alih-alih membuka file temp di direktori tempat Anda berada, sebenarnya akan secara otomatis membuatnya di direktori data aplikasi (pada Windows) dan dari mereka Anda dapat melakukan file.unlink untuk menghapusnya ..
13aal
3
Saya sangat menghargai pemikiran ekstra yang dimasukkan ke dalam hal ini. Sebagai seorang pemula, sangat menarik untuk melihat pola pikir dari developer berpengalaman yang tidak hanya dapat menjawab pertanyaan awal, tetapi juga mengomentari konteks yang lebih luas dari apa sebenarnya arti pertanyaan asli.
ramijames
Pemrograman bukan hanya tentang memperbaiki masalah langsung, ini juga tentang berpikir jauh ke depan untuk menghindari masalah lain yang menunggu. Tidak ada yang lebih mengganggu pengembang senior selain menemukan kode yang mengecat algoritme menjadi sudut, memaksa kludge yang canggung, ketika penyesuaian kecil sebelumnya akan menghasilkan aliran yang bagus. Analisis dapat memakan waktu berjam-jam, atau berhari-hari untuk memahami tujuan, dan kemudian beberapa baris menggantikan halaman kode lama. Ini seperti permainan catur melawan data dan sistem pada waktu tertentu.
Tin Man
11
Sebenarnya tidak ada cara untuk mengedit file di tempat. Apa yang biasanya Anda lakukan ketika Anda dapat melakukannya (misalnya jika file tidak terlalu besar) adalah, Anda membaca file ke dalam memori ( File.read), melakukan penggantian pada string baca ( String#gsub) dan kemudian menulis string yang diubah kembali ke file ( File.open, File#write).
Jika file cukup besar sehingga tidak dapat digunakan, yang perlu Anda lakukan, adalah membaca file dalam potongan (jika pola yang ingin Anda ganti tidak akan menjangkau banyak baris maka satu potongan biasanya berarti satu baris - Anda dapat menggunakannya File.foreachuntuk membaca file baris demi baris), dan untuk setiap potongan melakukan substitusi di atasnya dan menambahkannya ke file sementara. Ketika Anda selesai mengulang file sumber, Anda menutupnya dan menggunakan FileUtils.mvuntuk menimpanya dengan file sementara.
Saya suka pendekatan streaming. Kami menangani file besar secara bersamaan sehingga kami biasanya tidak memiliki ruang dalam RAM untuk membaca seluruh file
Pendekatan lain adalah dengan menggunakan pengeditan di dalam Ruby (bukan dari baris perintah):
#!/usr/bin/rubydef inplace_edit(file, bak,&block)
old_stdout = $stdout
argf = ARGF.clone
argf.argv.replace [file]
argf.inplace_mode = bak
argf.each_line do|line|yield line
end
argf.close
$stdout = old_stdout
end
inplace_edit 'test.txt','.bak'do|line|
line = line.gsub(/search1/,"replace1")
line = line.gsub(/search2/,"replace2")
print line unless line.match(/something/)end
Jika Anda tidak ingin membuat cadangan, ubah '.bak'ke ''.
Ini akan lebih baik daripada mencoba slurp ( read) file. Ini dapat diskalakan dan harus sangat cepat.
Manusia Timah
Ada bug di suatu tempat yang menyebabkan Ruby 2.3.0p0 di Windows gagal dengan izin ditolak jika ada beberapa blok inplace_edit berturut-turut yang bekerja pada file yang sama. Untuk mereproduksi tes split search1 dan search2 menjadi 2 blok. Tidak menutup sepenuhnya?
mlt
Saya mengharapkan masalah dengan beberapa pengeditan file teks yang terjadi secara bersamaan. Jika tidak ada yang lain, Anda bisa mendapatkan file teks yang rusak parah.
Berikut adalah solusi untuk menemukan / mengganti di semua file dari direktori tertentu. Pada dasarnya saya mengambil jawaban yang diberikan oleh sepp2k dan mengembangkannya.
# First set the files to search/replace in
files =Dir.glob("/PATH/*")# Then set the variables for find/replace@original_string_or_regex=/REGEX/@replacement_string="STRING"
files.each do|file_name|
text =File.read(file_name)
replace = text.gsub!(@original_string_or_regex,@replacement_string)File.open(file_name,"w"){|file| file.puts replace }end
Akan lebih membantu jika Anda memberikan penjelasan mengapa ini adalah solusi yang disukai dan menjelaskan cara kerjanya. Kami ingin mendidik, bukan hanya memberikan kode.
Tin Man
trollop berganti nama menjadi optimist github.com/manageiq/optimist . Juga itu hanya parser opsi CLI yang tidak benar-benar diperlukan untuk menjawab pertanyaan.
noraj
1
Jika Anda perlu melakukan substitusi melintasi batas garis, maka penggunaan ruby -pi -etidak akan berfungsi karena pprosesnya satu baris dalam satu waktu. Sebagai gantinya, saya merekomendasikan yang berikut ini, meskipun bisa gagal dengan file multi-GB:
Pencarian spasi putih (kemungkinan termasuk baris baru) diikuti dengan kutipan, dalam hal ini menghilangkan spasi. Ini %q(')hanyalah cara yang bagus untuk mengutip karakter kutipan.
* .txt dapat diganti dengan pilihan lain atau dengan beberapa nama file atau jalur
rusak sehingga saya bisa menjelaskan apa yang terjadi tetapi masih dapat dieksekusi
# ARGV is an array of the arguments passed to the script.
ARGV[0..-3].each do|f|# enumerate the arguments of this script from the first to the last (-1) minus 2File.write(f,# open the argument (= filename) for writingFile.read(f)# open the argument (= filename) for reading.gsub(ARGV[-2],ARGV[-1]))# and replace all occurances of the beforelast with the last argument (string)end
EDIT: jika Anda ingin menggunakan ekspresi reguler gunakan ini sebagai gantinya Jelas, ini hanya untuk menangani file teks yang relatif kecil, tidak ada monster Gigabyte
Kode ini tidak akan berfungsi. Saya sarankan mengujinya sebelum memposting, lalu salin dan tempel kode yang berfungsi.
Tin Man
@ theTinMan Saya selalu menguji sebelum menerbitkan, jika memungkinkan. Saya menguji ini dan berhasil, baik versi singkat sebagai komentar. Menurut Anda, mengapa tidak?
peter
jika Anda bermaksud menggunakan ekspresi reguler lihat suntingan saya, juga diuji:>)
File.read
perlu disesuaikan dengan informasi di stackoverflow.com/a/25189286/128421 untuk mengapa menyeruput file besar itu buruk. Juga, alih-alihFile.open(filename, "w") { |file| file << content }
menggunakan variasiFile.write(filename, content)
.Jawaban:
Penafian: Pendekatan ini adalah ilustrasi naif dari kemampuan Ruby, dan bukan solusi tingkat produksi untuk mengganti string dalam file. Ini rentan terhadap berbagai skenario kegagalan, seperti kehilangan data jika terjadi crash, interupsi, atau disk penuh. Kode ini tidak cocok untuk apa pun selain skrip cepat satu kali yang semua datanya dicadangkan. Oleh karena itu, JANGAN menyalin kode ini ke dalam program Anda.
Berikut cara singkat dan cepat untuk melakukannya.
sumber
File.write(file_name, text.gsub(/regexp/, "replace")
Sebenarnya, Ruby memiliki fitur pengeditan di tempat. Seperti Perl, bisa dibilang
Ini akan menerapkan kode dalam tanda kutip ganda ke semua file di direktori saat ini yang namanya diakhiri dengan ".txt". Salinan cadangan dari file yang diedit akan dibuat dengan ekstensi ".bak" ("foobar.txt.bak" menurut saya).
CATATAN: ini tampaknya tidak berfungsi untuk pencarian multiline. Untuk itu, Anda harus melakukannya dengan cara lain yang kurang cantik, dengan skrip pembungkus di sekitar regex.
sumber
<main>': undefined method
gsub 'untuk main: Object (NoMethodError)-i
mengedit di tempat..bak
adalah ekstensi yang digunakan untuk file cadangan (opsional).-p
adalah sesuatu sepertiwhile gets; <script>; puts $_; end
. ($_
adalah baris baca terakhir, tetapi Anda dapat menetapkannya untuk sesuatu sepertiecho aa | ruby -p -e '$_.upcase!'
.)Ingatlah bahwa, ketika Anda melakukan ini, sistem file mungkin kehabisan ruang dan Anda dapat membuat file dengan panjang nol. Ini bencana jika Anda melakukan sesuatu seperti menulis file / etc / passwd sebagai bagian dari manajemen konfigurasi sistem.
Perhatikan bahwa pengeditan file di tempat seperti pada jawaban yang diterima akan selalu memotong file dan menulis file baru secara berurutan. Akan selalu ada kondisi balapan di mana pembaca yang bersamaan akan melihat file yang terpotong. Jika proses dibatalkan karena alasan apa pun (ctrl-c, OOM killer, system crash, power outage, dll) selama penulisan, maka file yang terpotong juga akan tertinggal, yang dapat menjadi bencana besar. Ini adalah jenis skenario dataloss yang HARUS dipertimbangkan oleh pengembang karena itu akan terjadi. Untuk alasan itu, saya pikir jawaban yang diterima kemungkinan besar bukan jawaban yang diterima. Minimal tulis ke tempfile dan pindahkan / ganti nama file ke tempatnya seperti solusi "sederhana" di akhir jawaban ini.
Anda perlu menggunakan algoritme yang:
Membaca file lama dan menulis ke file baru. (Anda harus berhati-hati saat memasukkan seluruh file ke dalam memori).
Menutup file sementara baru secara eksplisit, di mana Anda dapat melontarkan pengecualian karena buffer file tidak dapat ditulis ke disk karena tidak ada ruang. (Tangkap ini dan bersihkan file sementara jika Anda mau, tetapi Anda perlu mengembalikan sesuatu atau gagal cukup keras saat ini.
Memperbaiki izin dan mode file pada file baru.
Ubah nama file baru dan letakkan di tempatnya.
Dengan sistem file ext3 Anda dijamin bahwa penulisan metadata untuk memindahkan file ke tempatnya tidak akan diatur ulang oleh sistem file dan ditulis sebelum buffer data untuk file baru ditulis, jadi ini akan berhasil atau gagal. Sistem file ext4 juga telah ditambal untuk mendukung perilaku semacam ini. Jika Anda sangat paranoid, Anda harus memanggil panggilan
fdatasync()
sistem sebagai langkah 3.5 sebelum memindahkan file ke tempatnya.Terlepas dari bahasanya, ini adalah praktik terbaik. Dalam bahasa di mana pemanggilan
close()
tidak memunculkan pengecualian (Perl atau C), Anda harus secara eksplisit memeriksa kembalinyaclose()
dan melempar pengecualian jika gagal.Saran di atas untuk hanya menghirup file ke dalam memori, memanipulasinya, dan menulisnya ke file akan dijamin menghasilkan file dengan panjang nol pada sistem file penuh. Anda harus selalu menggunakan
FileUtils.mv
untuk memindahkan file sementara yang ditulis lengkap ke tempatnya.Pertimbangan terakhir adalah penempatan file sementara. Jika Anda membuka file di / tmp maka Anda harus mempertimbangkan beberapa masalah:
Jika / tmp dipasang pada sistem file yang berbeda, Anda dapat menjalankan / tmp kehabisan ruang sebelum Anda menulis file yang seharusnya dapat diterapkan ke tujuan file lama.
Mungkin yang lebih penting, ketika Anda mencoba
mv
file di perangkat mount Anda akan secara transparan diubah kecp
perilaku. File lama akan dibuka, inode file lama akan dipertahankan dan dibuka kembali dan konten file akan disalin. Ini kemungkinan besar bukan yang Anda inginkan, dan Anda mungkin mengalami kesalahan "file teks sibuk" jika Anda mencoba mengedit konten file yang sedang berjalan. Ini juga menggagalkan tujuan penggunaanmv
perintah sistem berkas dan Anda dapat menjalankan sistem berkas tujuan di luar ruang dengan hanya berkas yang ditulis sebagian.Ini juga tidak ada hubungannya dengan implementasi Ruby. Sistem
mv
dancp
perintah berperilaku serupa.Apa yang lebih disukai adalah membuka Tempfile di direktori yang sama dengan file lama. Ini memastikan bahwa tidak akan ada masalah perpindahan lintas perangkat. Itu
mv
sendiri tidak akan pernah gagal, dan Anda harus selalu mendapatkan file yang lengkap dan tidak terpotong. Kegagalan apa pun, seperti perangkat kehabisan ruang, kesalahan izin, dll., Harus ditemui selama penulisan Tempfile.Satu-satunya kelemahan pendekatan pembuatan Tempfile di direktori tujuan adalah:
Berikut beberapa kode yang menerapkan algoritme lengkap (kode windows belum teruji dan belum selesai):
Dan ini adalah versi yang sedikit lebih ketat yang tidak mengkhawatirkan setiap kemungkinan kasus tepi (jika Anda menggunakan Unix dan tidak peduli tentang menulis ke / proc):
Kasus penggunaan yang sangat sederhana, ketika Anda tidak peduli dengan izin sistem file (baik Anda tidak menjalankan sebagai root, atau Anda menjalankan sebagai root dan file tersebut dimiliki root):
TL; DR : Itu setidaknya harus digunakan sebagai ganti jawaban yang diterima, dalam semua kasus, untuk memastikan pembaruan bersifat atomic dan pembaca yang bersamaan tidak akan melihat file yang terpotong. Seperti yang saya sebutkan di atas, membuat Tempfile di direktori yang sama dengan file yang diedit penting di sini untuk menghindari operasi mv lintas perangkat diterjemahkan ke dalam operasi cp jika / tmp dipasang pada perangkat yang berbeda. Memanggil fdatasync adalah lapisan tambahan dari paranoia, tetapi akan menimbulkan performa yang buruk, jadi saya menghilangkannya dari contoh ini karena hal ini tidak umum dilakukan.
sumber
Sebenarnya tidak ada cara untuk mengedit file di tempat. Apa yang biasanya Anda lakukan ketika Anda dapat melakukannya (misalnya jika file tidak terlalu besar) adalah, Anda membaca file ke dalam memori (
File.read
), melakukan penggantian pada string baca (String#gsub
) dan kemudian menulis string yang diubah kembali ke file (File.open
,File#write
).Jika file cukup besar sehingga tidak dapat digunakan, yang perlu Anda lakukan, adalah membaca file dalam potongan (jika pola yang ingin Anda ganti tidak akan menjangkau banyak baris maka satu potongan biasanya berarti satu baris - Anda dapat menggunakannya
File.foreach
untuk membaca file baris demi baris), dan untuk setiap potongan melakukan substitusi di atasnya dan menambahkannya ke file sementara. Ketika Anda selesai mengulang file sumber, Anda menutupnya dan menggunakanFileUtils.mv
untuk menimpanya dengan file sementara.sumber
Pendekatan lain adalah dengan menggunakan pengeditan di dalam Ruby (bukan dari baris perintah):
Jika Anda tidak ingin membuat cadangan, ubah
'.bak'
ke''
.sumber
read
) file. Ini dapat diskalakan dan harus sangat cepat.Ini bekerja untuk saya:
sumber
Berikut adalah solusi untuk menemukan / mengganti di semua file dari direktori tertentu. Pada dasarnya saya mengambil jawaban yang diberikan oleh sepp2k dan mengembangkannya.
sumber
sumber
Jika Anda perlu melakukan substitusi melintasi batas garis, maka penggunaan
ruby -pi -e
tidak akan berfungsi karenap
prosesnya satu baris dalam satu waktu. Sebagai gantinya, saya merekomendasikan yang berikut ini, meskipun bisa gagal dengan file multi-GB:Pencarian spasi putih (kemungkinan termasuk baris baru) diikuti dengan kutipan, dalam hal ini menghilangkan spasi. Ini
%q(')
hanyalah cara yang bagus untuk mengutip karakter kutipan.sumber
Berikut alternatif satu liner dari jim, kali ini dalam skrip
Simpan dalam sebuah script, mis. Replace.rb
Anda mulai pada baris perintah dengan
* .txt dapat diganti dengan pilihan lain atau dengan beberapa nama file atau jalur
rusak sehingga saya bisa menjelaskan apa yang terjadi tetapi masih dapat dieksekusi
EDIT: jika Anda ingin menggunakan ekspresi reguler gunakan ini sebagai gantinya Jelas, ini hanya untuk menangani file teks yang relatif kecil, tidak ada monster Gigabyte
sumber