Apa cara paling sederhana untuk mencari dan mengganti string input yang diberikan, katakan abc
, dan ganti dengan string lain, katakan XYZ
dalam file /tmp/file.txt
?
Saya sedang menulis aplikasi dan menggunakan IronPython untuk menjalankan perintah melalui SSH - tetapi saya tidak tahu Unix dengan baik dan tidak tahu apa yang harus dicari.
Saya telah mendengar bahwa Bash, selain sebagai antarmuka baris perintah, dapat menjadi bahasa scripting yang sangat kuat. Jadi, jika ini benar, saya berasumsi Anda dapat melakukan tindakan seperti ini.
Bisakah saya melakukannya dengan bash, dan skrip apa yang paling sederhana (satu baris) untuk mencapai tujuan saya?
sed
:s/..../..../ - Substitute
dan/g - Global
invalid command code C
kesalahan ... Untuk penggantian di tempat, BSDsed
memerlukan ekstensi file setelah-i
flag karena menyimpan file cadangan dengan ekstensi yang diberikan. Sebagai contoh:sed -i '.bak' 's/find/replace/' /file.txt
Anda dapat melewatkan cadangan dengan menggunakan string kosong seperti:sed -i '' 's/find/replace/' /file.txt
s/abc/XYZ/gi
Manipulasi file biasanya tidak dilakukan oleh Bash, tetapi oleh program yang dipanggil oleh Bash, misalnya:
The
-i
flag mengatakan itu untuk melakukan penggantian di tempat.Lihat
man perlrun
untuk detail lebih lanjut, termasuk cara mengambil cadangan file asli.sumber
perl -pi -e 's/chdir (?:\\/[\\w\\.\\-]+)+/chdir blah/g' text
, tetapi saya terus mendapatkan kesalahan dengan Tidak memiliki ruang antara pola dan kata berikut sudah ditinggalkan pada -e baris 1. Tidak cocok (dalam regex; ditandai dengan <- DI SINI di m / (chdir) () (<- DI SINI ?: \\ / at -e line 1.Saya terkejut ketika saya menemukan ini ...
Ada
replace
perintah yang dikirimkan bersama"mysql-server"
paket, jadi jika Anda telah menginstalnya, cobalah:Lihat
man replace
lebih lanjut tentang ini.sumber
replace
adalah alat independen yang berguna dan orang-orang MySQL harus melepaskannya secara terpisah dan bergantung padanya b)replace
memerlukan sedikit MySQL o_O Either way, menginstal mysql-server untuk mendapatkan penggantian akan menjadi hal yang salah untuk dilakukan :)mysql-server
menginstal paket. Seperti yang ditunjukkan oleh @rayro,replace
adalah bagian dari itu.Ini adalah pos lama tetapi bagi siapa pun yang ingin menggunakan variabel seperti @centurian mengatakan tanda kutip tunggal berarti tidak ada yang akan diperluas.
Cara sederhana untuk mendapatkan variabel adalah dengan melakukan penggabungan string karena ini dilakukan dengan menyandingkan di bash, yang berikut ini akan berfungsi:
sumber
Bash, seperti shell lainnya, hanyalah alat untuk mengoordinasikan perintah lain. Biasanya Anda akan mencoba menggunakan perintah UNIX standar, tetapi tentu saja Anda dapat menggunakan Bash untuk memanggil apa pun, termasuk program yang Anda buat sendiri, skrip shell lain, skrip Python dan Perl, dll.
Dalam hal ini, ada beberapa cara untuk melakukannya.
Jika Anda ingin membaca file, dan menulisnya ke file lain, melakukan pencarian / ganti saat Anda pergi, gunakan sed:
Jika Anda ingin mengedit file pada tempatnya (seolah membuka file dalam editor, mengeditnya, lalu menyimpannya) berikan instruksi ke editor baris 'ex'
Ex seperti vi tanpa mode layar penuh. Anda dapat memberikannya perintah yang sama dengan yang Anda minta di prompt ':' vi.
sumber
Saya menemukan utas ini di antara yang lain dan saya setuju itu berisi jawaban yang paling lengkap sehingga saya juga menambahkan utas saya:
sed
daned
sangat berguna ... dengan tangan. Lihat kode ini dari @Johnny:Ketika batasan saya adalah menggunakannya dalam skrip shell, tidak ada variabel yang dapat digunakan di dalam menggantikan "abc" atau "XYZ". The BashFAQ tampaknya setuju dengan apa yang saya mengerti setidaknya. Jadi, saya tidak bisa menggunakan:
tapi, apa yang bisa kita lakukan? Seperti, @Johnny berkata gunakan
while read...
tapi, sayangnya itu bukan akhir dari cerita. Berikut ini bekerja dengan baik untuk saya:Seperti yang dapat dilihat jika
nullglob
diatur kemudian, itu berperilaku aneh ketika ada string yang mengandung*
seperti pada:yang menjadi
tidak ada bracket sudut ujung dan Apache2 bahkan tidak bisa memuat.
Penguraian seperti ini harus lebih lambat dari pencarian sekali pakai dan ganti tetapi, seperti yang sudah Anda lihat, ada empat variabel untuk empat pola pencarian berbeda yang bekerja pada satu siklus penguraian.
Solusi yang paling cocok yang bisa saya pikirkan dengan asumsi masalah yang diberikan.
sumber
sed -e "s/$x/$y/"
, dan itu akan berhasil. Bukan kutipan ganda. Itu bisa sangat membingungkan jika string dalam variabel itu sendiri mengandung karakter dengan makna khusus. Misalnya jika x = "/" atau x = "\". Ketika Anda mengalami masalah ini, itu mungkin berarti Anda harus berhenti mencoba menggunakan shell untuk pekerjaan ini.Anda bisa menggunakan
sed
:Gunakan
-i
untuk "abaikan case" jika Anda tidak yakin teksnya ditemukanabc
atauABC
atauAbC
, dll.Anda dapat menggunakan
find
dansed
jika Anda tidak tahu nama file Anda:Temukan dan ganti semua file Python:
sumber
Anda juga dapat menggunakan
ed
perintah untuk melakukan pencarian dalam file dan mengganti:Lihat lebih banyak di " Mengedit file melalui skrip dengan
ed
".sumber
sed -i <pattern> <filename>
). Sangat bagus!Jika file yang sedang Anda kerjakan tidak terlalu besar, dan menyimpannya sementara dalam suatu variabel tidak menjadi masalah, maka Anda dapat menggunakan subtitusi Bash string pada seluruh file sekaligus - tidak perlu untuk membahasnya baris demi baris:
Seluruh isi file akan diperlakukan sebagai satu string panjang, termasuk linebreak.
XYZ dapat berupa variabel misalnya
$replacement
, dan satu keuntungan dari tidak menggunakan sed di sini adalah Anda tidak perlu khawatir bahwa pencarian atau penggantian string mungkin berisi karakter pembatas pola sed (biasanya, tetapi tidak harus, /). Kerugiannya adalah tidak bisa menggunakan ekspresi reguler atau operasi sed yang lebih canggih.sumber
Hati-hati jika Anda mengganti URL dengan karakter "/".
Contoh cara melakukannya:
Diambil dari: http://www.sysadmit.com/2015/07/linux-reemplazar-texto-en-archivos-con-sed.html
sumber
Coba perintah shell berikut:
sumber
sed
, gunakansed -i''
saja.Untuk mengedit teks dalam file secara non-interaktif, Anda memerlukan editor teks in-place seperti vim.
Berikut adalah contoh sederhana cara menggunakannya dari baris perintah:
Ini setara dengan jawaban @slim dari mantan editor yang pada dasarnya adalah hal yang sama.
Berikut adalah beberapa
ex
contoh praktis.Mengganti teks
foo
denganbar
dalam file:Menghapus jejak spasi putih untuk banyak file:
Pemecahan masalah (ketika terminal macet):
-V1
param untuk menampilkan pesan verbose.-cwq!
.Lihat juga:
sumber
-V1
, untuk memaksa berhenti, gunakanwq!
.Anda juga bisa menggunakan python dalam skrip bash. Saya tidak terlalu sukses dengan beberapa jawaban teratas di sini, dan menemukan ini berfungsi tanpa perlu pengulangan:
sumber
Anda dapat menggunakan perintah rpl. Misalnya Anda ingin mengubah nama domain di seluruh proyek php.
Ini bukan penyebab yang jelas, tetapi sangat cepat dan bermanfaat. :)
sumber