Saya ingin mencari dan mengganti beberapa teks dalam satu set besar file tidak termasuk beberapa contoh. Untuk setiap baris, saya ingin meminta menanyakan apakah saya perlu mengganti baris itu atau tidak. Sesuatu yang mirip dengan vim :%s/from/to/gc
(dengan c
untuk meminta konfirmasi), tetapi di seluruh set folder. Apakah ada alat atau skrip baris perintah yang baik yang dapat digunakan?
11
s/from/to/g
dengan kesalahan pemformatan setelahnya, bukans/from/to/gc
dengan penekanan padac
saat Anda berusaha menulis (Anda tidak dapat melakukannya dengan Markdown, Anda bisa melakukannya dengan<code>
dan<strong>
tag HTML).Jawaban:
Mengapa tidak menggunakan vim?
Buka semua file dalam vim
Atau hanya buka file yang relevan (seperti yang disarankan oleh Caleb)
Dan kemudian jalankan ganti di semua buffer
Anda juga dapat melakukannya dengan
sed
, tetapi pengetahuan saya terbatas.sumber
grep
alih-alihfind
sehingga Anda hanya membuka file yang telah diketahui cocok.vim $(grep 'from' . -Rl)
Anda dapat melakukan sesuatu yang kasar dengan skrip Perl kecil yang diperintahkan untuk melakukan penggantian baris demi baris (
-l -pe
) pada file yang diteruskan sebagai argumen (-i
):Peningkatan yang mungkin dilakukan adalah mewarnai bagian prompt dan mendukung hal-hal seperti "ganti semua kejadian di file saat ini". Meminta secara terpisah untuk setiap kemunculan pada sebuah garis akan lebih sulit.
Bagian kedua, mencocokkan file. jika tidak terlalu banyak file yang terlibat dan Anda menjalankan zsh, Anda dapat mencocokkan semua file di direktori saat ini dan subdirektori secara rekursif:
Jika shell Anda adalah bash ≥4, Anda dapat menjalankan
perl … **/*
, tetapi itu akan menghasilkan pesan kesalahan palsu karena sed akan mencoba (dan gagal) untuk berjalan pada direktori. Jika Anda hanya ingin melakukan penggantian dalam satu set file seperti file C, Anda dapat membatasi kecocokan (yang bekerja pada bash ≥4 atau zsh):Jika Anda perlu kontrol yang lebih baik atas file mana yang Anda ganti, atau shell Anda tidak memiliki konstruksi pencocokan direktori rekursif
**
, atau jika Anda memiliki terlalu banyak file dan mendapatkan kesalahan "baris perintah terlalu lama", gunakanfind
. Misalnya, untuk melakukan penggantian di semua file bernama*.h
atau*.c
di direktori saat ini dan subdirektori (pada sistem yang lebih lama, Anda mungkin perlu menggunakan\;
alih-alih+
di akhir baris (+
formulir lebih cepat tetapi tidak tersedia di mana-mana).Yang sedang berkata, saya akan tetap menjadi editor interaktif jika Anda membutuhkan interaksi. Gert telah menunjukkan cara untuk melakukan ini di Vim , meskipun itu mengharuskan membuka semua file yang ingin Anda cari, yang mungkin menjadi masalah jika ada banyak.
Di Emacs, inilah cara Anda dapat melakukan ini:
M-x find-name-dired
(tentukan direktori tingkat atas) atauM-x find-dired
(tentukanfind
baris perintah arbitrer ).t
untuk menandai semua file, laluQ
(dired-do-query-replace-regexp
) untuk melakukan penggantian dengan meminta pada file yang ditandai.sumber
sdiff
(lihat http://www.gnu.org/software/diffutils/manual/diffutils.html#Invoking-sdiff ) mungkin berguna di sini. Dengan itu Anda dapat melakukan penambalan interaktif. Jadi melakukannya dengan file sementara yang Anda buat dengan melakukan operasi penggantian menggunakansed
mungkin merupakan solusi yang mungkin:(File loop menggunakan subtitusi proses non-POSIX dan
read -d
seperti yang didukung misalnya olehbash
.)sumber