Saya perlu mengganti string di banyak file dalam folder, dengan hanya ssh
akses ke server. Bagaimana saya bisa melakukan ini?
461
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
Kemunculan "foo" akan diganti dengan "bar".
Pada sistem BSD seperti macOS, Anda perlu memberikan ekstensi cadangan seperti -i '.bak'
atau "risiko risiko atau konten parsial" lainnya atau per halaman manual.
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
sed
,-i
membutuhkan string setelahnya, yang ditambahkan ke nama file lama. Jadised -i .bak 's/foo/bar/g' *.xx
pindahkan semua.xx
file ke.xx.bak
nama yang setara dan kemudian hasilkan.xx
file dengan substitusi foo → bar.sed -i 's/foo\ with\ spaces/bar/g' *
. Saya kira Anda sudah tahu setelah sekian lama ... tetapi cara ini tetap untuk orang lain menemukan masalah yang sama.sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)
Mirip dengan jawaban Kaspar tetapi dengan flag g untuk menggantikan semua kemunculan pada sebuah garis.
Untuk case global tidak sensitif:
sumber
LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \;
(lihat posting ini dan ini )--include=*.whatever
dengan -r.git/
. Pastikan untukcd
turun ke level yang lebih rendah.git status
kembali:error: bad index file sha1 signature.... fatal: index file corrupt
. Apa yang menyebabkannya?Jawaban @ kev baik, tetapi hanya memengaruhi file di direktori langsung. Contoh di bawah ini menggunakan grep untuk menemukan file secara rekursif. Ini bekerja untuk saya setiap saat.
Perintah rusak
grep -r : --recursive , secara rekursif membaca semua file di bawah setiap direktori.
grep -l : --print-with-cocok , mencetak nama setiap file yang memiliki kecocokan, bukan mencetak baris yang cocok.
grep -i : --ignore-case .
xargs : mengubah STDIN menjadi argumen, ikuti jawaban ini .
Perintah xargs -i @ ~ berisi @ ~ : pengganti untuk argumen yang akan digunakan pada posisi tertentu dalam ~ perintah ~ , tanda @ adalah pengganti yang bisa diganti dengan string apa pun.
sed -i : mengedit file di tempat, tanpa cadangan.
sed s / regexp / replacement / : pengganti senar string regexp dengan penggantian .
sed s / regexp / replacement / g : global , buat substitusi untuk setiap pertandingan, bukan hanya pertandingan pertama.
sumber
grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @
|
, juga, mengapa-i
dalam perintah xargs? Saya membaca dalam manual itu sudah usang dan harus digunakan-I
sebagai gantinya. Dan@
digunakan sebagai pembatas untuk awal dan akhir untuk pola?grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @
rli
) dan@
tanda misalnyaIni bekerja untuk saya:
Howerver, ini tidak:
sed -i 's/string1/string2/g' *
. Mungkin "foo" tidak dimaksudkan sebagai string1 dan "bar" bukan string2.sumber
find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;
Ada beberapa jawaban standar untuk ini sudah terdaftar. Secara umum, Anda dapat menggunakan find untuk mendaftarkan file secara rekursif dan kemudian melakukan operasi dengan sed atau perl .
Untuk sebagian besar penggunaan cepat, Anda mungkin menemukan perintah rpl jauh lebih mudah diingat. Berikut ini adalah penggantian (foo -> bar), secara rekursif pada semua file:
rpl -R foo bar .
Anda mungkin harus menginstalnya (
apt-get install rpl
atau serupa).Namun, untuk pekerjaan yang lebih sulit yang melibatkan ekspresi reguler dan penggantian belakang, atau mengganti nama file serta mencari dan mengganti, alat paling umum dan kuat yang saya ketahui adalah repren , skrip Python kecil yang saya tulis beberapa waktu lalu untuk beberapa penggantian nama dan tugas refactoring yang lebih sulit. Alasan yang mungkin Anda sukai adalah:
Untuk menggunakannya
pip install repren
,. Periksa README untuk contoh.sumber
Untuk mengganti string di banyak file, Anda dapat menggunakan:
Misalnya
Sumber blog
sumber
Untuk mengganti jalur di dalam file (menghindari karakter melarikan diri), Anda dapat menggunakan perintah berikut:
Tanda @ berarti bahwa semua karakter khusus harus diabaikan dalam string berikut.
sumber
Jika string Anda memiliki garis miring (/) di dalamnya, Anda bisa mengubah pembatas menjadi '+'.
Perintah ini akan berjalan secara rekursif di direktori saat ini.
sumber
../domain.com
kedomain.com
Kejadian baris pertama dari "foo" akan diganti dengan "bar". Dan Anda dapat menggunakan baris kedua untuk memeriksa.
sumber
grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
Jika Anda memiliki daftar file yang dapat Anda gunakan
Jika Anda memiliki semua file yang dapat Anda gunakan
Jika Anda memiliki daftar file dengan ekstensi, Anda dapat menggunakan
sumber
replace "old_string" "new_string" -- *.txt
replace
utilitas ini . Tanpa informasi ini, jawaban ini tidak lengkap."Kamu juga bisa menggunakan find dan sed, tetapi aku menemukan bahwa garis kecil perl ini bekerja dengan baik.
"(Diekstrak dari http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php )
Hasil terbaik saya berasal dari menggunakan perl dan grep (untuk memastikan file memiliki ekspresi pencarian)
sumber
Mengingat Anda ingin mencari string
search
dan menggantinya denganreplace
banyak file, ini adalah formula satu-baris saya yang telah teruji pertempuran :Penjelasan grep cepat:
-R
- Pencarian rekursif-i
- case-insensitive-I
- lewati file biner (Anda ingin teks, bukan?)-l
- cetak daftar sederhana sebagai keluaran. Dibutuhkan untuk perintah lainOutput grep kemudian disalurkan ke sed (melalui xargs) yang digunakan untuk benar-benar mengganti teks. The
-i
bendera akan mengubah file secara langsung. Hapus itu untuk semacam mode "dry run".sumber
Saya membuat solusi sendiri sebelum saya menemukan pertanyaan ini (dan jawaban). Saya mencari berbagai kombinasi "ganti" "beberapa" dan "xml," karena itu adalah aplikasi saya, tetapi tidak menemukan yang satu ini.
Masalah saya: Saya punya file pegas xml dengan data untuk kasus uji, yang berisi objek kompleks. Refactor pada kode sumber java mengubah banyak kelas dan tidak berlaku untuk file data xml. Untuk menyimpan data kasus uji, saya perlu mengubah semua nama kelas di semua file xml, didistribusikan di beberapa direktori. Semua sambil menyimpan salinan cadangan dari file xml asli (meskipun ini bukan keharusan, karena kontrol versi akan menyelamatkan saya di sini).
Saya mencari beberapa kombinasi
find
+sed
, karena berfungsi untuk saya dalam situasi lain, tetapi tidak dengan beberapa penggantian sekaligus.Kemudian saya menemukan meminta respons ubuntu dan itu membantu saya membangun baris perintah:
Dan itu bekerja dengan sempurna (well, case saya memiliki enam penggantian berbeda). Tetapi harap dicatat bahwa itu akan menyentuh semua file * .xml di bawah direktori saat ini. Karena itu, dan jika Anda bertanggung jawab pada sistem kontrol versi, Anda mungkin ingin memfilter terlebih dahulu dan hanya meneruskannya kepada
sed
mereka yang benar-benar memiliki string yang Anda inginkan; Suka:sumber
findstr /spin /c:"quéquieresbuscar" *.xml
Ini akan berguna.sumber
Benar-benar lumpuh, tapi saya tidak bisa mendapatkan perintah sed untuk bekerja dengan benar pada OSX, jadi saya melakukan hal bodoh ini sebagai gantinya:
^ - salin ketiga baris ini ke clipboard saya (ya, termasuk baris akhir), lalu:
vi *
dan tahan perintah-v sampai dikatakan tidak ada file yang tersisa.
Dumb ... hacky ... efektif ...
sumber
Di MacBook Pro, saya menggunakan yang berikut ini (terinspirasi oleh https://stackoverflow.com/a/19457213/6169225 ):
sumber
-e
hanya mengatakan bahwa token berikutnya adalah sebuah perintah. Untuk ekspresi reguler yang diperluas, gunakan-E
saja.Editor aliran mengubah beberapa file “inplace” ketika dipanggil dengan
-i
sakelar, yang mengambil file cadangan yang berakhir sebagai argumen. Begitumenggantikan
foo
denganbar
semua file dalam folder ini, tetapi tidak turun ke subfolder. Namun ini akan menghasilkan.bak
file baru untuk setiap file di direktori Anda. Untuk melakukan ini secara rekursif untuk semua file di direktori ini dan semua subdirektori, Anda perlu bantuan, sepertifind
, untuk melintasi pohon direktori.find
memungkinkan Anda pembatasan lebih lanjut pada file apa yang akan dimodifikasi, dengan menentukan argumen lebih lanjut sepertifind ./ -name '*.php' -or -name '*.html' -print0
, jika perlu.Catatan: GNU
sed
tidak membutuhkan akhiran file, jugased -i 's/foo/bar/g' *
akan berfungsi; FreeBSDsed
menuntut ekstensi, tetapi memungkinkan ruang di antaranya, jadised -i .bak s/foo/bar/g *
berfungsi.sumber
skrip untuk perintah multiedit
Dari jawaban Kaspar saya membuat skrip bash untuk menerima argumen baris perintah dan secara opsional membatasi nama file yang cocok dengan suatu pola. Simpan $ PATH Anda dan buat executable, kemudian gunakan saja perintah di atas.
Ini skripnya:
sumber
Jika file tersebut berisi garis miring terbalik (biasanya jalur) Anda dapat mencoba sesuatu seperti ini:
ex:
sumber
Untuk mempertahankan simpul bahasa Inggris pribadi saya, saya menulis sebuah skrip utilitas yang membantu mengganti beberapa pasangan string lama / baru, untuk semua file di bawah direktori secara rekursif.
Pasangan multipel string lama / baru dikelola di peta hash.
Dir dapat diatur melalui baris perintah atau variabel lingkungan, peta dikodekan dalam skrip, tetapi Anda dapat memodifikasi kode untuk memuat dari file, jika perlu.
Ini membutuhkan bash 4.2, karena beberapa fitur baru.
en_standardize.sh:
sumber
Menggunakan perintah ack akan jauh lebih cepat seperti ini:
Juga jika Anda memiliki ruang putih di hasil pencarian. Anda harus menghindarinya.
sumber
Saya memberikan contoh untuk memperbaiki kesalahan shebang umum dalam sumber python.
Anda dapat mencoba pendekatan grep / sed. Ini adalah yang berfungsi dengan GNU dan tidak akan merusak repo git:
Atau Anda bisa menggunakan greptile :)
Saya baru saja menguji skrip pertama, dan yang kedua juga harus berfungsi. Hati-hati dengan karakter pelarian, saya pikir seharusnya lebih mudah menggunakan greptile dalam banyak kasus. Tentu saja, Anda dapat melakukan banyak hal menarik dengan sed, dan untuk itu mungkin lebih baik untuk menguasai menggunakannya dengan xargs.
sumber
Saya menemukan ini dari posting lain (tidak ingat yang mana) dan meskipun bukan yang paling elegan, itu sederhana dan sebagai pengguna Linux pemula telah memberi saya tidak ada masalah
jika Anda memiliki spasi atau karakter khusus lainnya gunakan \
untuk string dalam penggunaan sub-direktori **
sumber
Perintah di bawah ini dapat digunakan untuk pertama mencari file dan mengganti file:
Sebagai contoh
sumber
Ada cara yang lebih mudah dengan menggunakan file skrip sederhana:
buka file di gedit atau editor pilihan Anda, saya menggunakan gedit di sini.
Kemudian pada editor tempel yang berikut ini di dalam file
Simpan file, tutup gedit , lalu keluar dari terminal Anda atau tutup saja dan mulai untuk dapat memuat skrip baru yang Anda tambahkan.
Arahkan ke direktori tempat Anda memiliki banyak file yang ingin Anda edit. Lalu lari:
Tekan enter dan ini akan secara otomatis mengganti oldstring dan oldstring1 di semua file yang berisi mereka dengan newstring yang benar dan newstring1 masing-masing.
Ini akan melewati semua direktori dan file yang tidak mengandung string lama.
Ini mungkin membantu menghilangkan pekerjaan mengetik yang membosankan jika Anda memiliki banyak direktori dengan file yang membutuhkan penggantian string. Yang harus Anda lakukan adalah menavigasi ke masing-masing direktori tersebut, lalu jalankan:
#replace_string_files_present_dir
Yang harus Anda lakukan adalah memastikan Anda telah memasukkan atau menambahkan semua string pengganti seperti yang saya tunjukkan di atas:
replace "oldstring" "newstring" -- *
di akhir file / bin / replace_string_files_present_dir .
Untuk menambahkan string pengganti yang baru, cukup buka skrip yang kami buat dengan mengetik berikut ini di terminal:
sudo gedit /bin/replace_string_files_present_dir
Jangan khawatir tentang jumlah string pengganti yang Anda tambahkan, mereka tidak akan berpengaruh jika tali lama tidak ditemukan.
sumber
.gitlab-ci.yml
atau atravis.yml
). Setiap putaran yang terdiri dari penulisan skrip untuk mengeksekusinya nanti adalah anti-pola, karena Anda akan perlu membuat skrip skrip (dan saya sering berantakan, sebagian besar waktu)$ ganti "Dari" "Ke" - `find / path / ke / folder -type f`
(ganti - utilitas pengganti string dari Sistem Database MySQL)
sumber