Bagaimana saya bisa menemukan dan mengganti kata-kata tertentu dalam file teks menggunakan baris perintah?
command-line
text-processing
Jon Doe
sumber
sumber
Jawaban:
Penjelasan:
sed
= Streaming Editor-i
= di tempat (mis. menyimpan kembali ke file asli)String perintah:
s
= perintah penggantioriginal
= ekspresi reguler yang menggambarkan kata yang akan diganti (atau hanya kata itu sendiri)new
= teks untuk menggantikannyag
= global (mis. ganti semua dan bukan hanya kejadian pertama)file.txt
= nama filesumber
sed
akan cocok dengan mereka. Tambahkan-r
bendera jika Anda ingin menggunakan RE yang diperluas sebagai gantinya./
karakter yang harus Anda cocokkan, Anda bisa menggunakan beberapa karakter lain sebagai pemisah (mis's_old/text_new/text_g'
.). Jika tidak, Anda dapat meletakkan\
sebelum apa pun$ * . [ \ ^
untuk mendapatkan karakter literal.sed -i '.bak' 's/original/new/g' file.txt
juga dapat dijalankan dengan ekstensi panjang nolsed -i '' 's/original/new/g' file.txt
, yang tidak akan menghasilkan cadangan.Ada sejumlah cara berbeda untuk melakukan ini. Salah satunya menggunakan
sed
dan Regex. SED adalah Editor Stream untuk memfilter dan mengubah teks. Salah satu contohnya adalah sebagai berikut:Cara lain yang mungkin lebih masuk akal daripada
< strin
dan> strout
adalah dengan pipa!sumber
cat
dicat file | sed '...'
tidak perlu. Anda bisa langsung bilangsed '...' file
.sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly
akan mengambil file yarly dan melakukan 2 perubahan di tempat sambil membuat cadangan. Menggunakantime bash -c "$COMMAND"
waktu itu menunjukkan bahwa versi ini ~ 5 kali lebih cepat.Ada banyak cara untuk mencapainya. Bergantung pada kerumitan apa yang ingin dicapai dengan penggantian string, dan tergantung pada alat yang akrab dengan pengguna, beberapa metode mungkin lebih disukai daripada yang lain.
Dalam jawaban ini saya menggunakan
input.txt
file sederhana , yang dapat Anda gunakan untuk menguji semua contoh yang disediakan di sini. Isi file:PESTA
Bash sebenarnya tidak dimaksudkan untuk pemrosesan teks, tetapi penggantian sederhana dapat dilakukan melalui ekspansi parameter , khususnya di sini kita dapat menggunakan struktur sederhana
${parameter/old_string/new_string}
.Skrip kecil ini tidak melakukan penggantian di tempat, artinya Anda harus menyimpan teks baru ke file baru, dan menyingkirkan file lama, atau
mv new.txt old.txt
Catatan: jika Anda ingin tahu mengapa
while IFS= read -r ; do ... done < input.txt
digunakan, ini pada dasarnya cara shell membaca baris per baris. Lihat ini untuk referensi.AWK
AWK, sebagai utilitas pemrosesan teks, cukup sesuai untuk tugas tersebut. Ia dapat melakukan penggantian sederhana dan yang lebih maju berdasarkan pada ekspresi reguler . Ini menyediakan dua fungsi:
sub()
dangsub()
. Yang pertama hanya menggantikan kejadian pertama, sedangkan yang kedua - menggantikan kejadian di seluruh string. Misalnya, jika kita memiliki stringone potato two potato
, ini akan menjadi hasilnya:AWK dapat mengambil file input sebagai argumen, jadi melakukan hal yang sama dengannya
input.txt
, akan mudah:Bergantung pada versi AWK yang Anda miliki, mungkin saja ada atau tidak ada pengeditan di tempat, maka praktik yang biasa dilakukan adalah menyimpan dan mengganti teks baru. Misalnya sesuatu seperti ini:
SED
Sed adalah editor baris. Itu juga menggunakan ekspresi reguler, tetapi untuk penggantian sederhana itu cukup untuk melakukan:
Apa yang baik tentang alat ini adalah memiliki pengeditan di tempat, yang dapat Anda aktifkan dengan
-i
flag.Perl
Perl adalah alat lain yang sering digunakan untuk pemrosesan teks, tetapi merupakan bahasa tujuan umum, dan digunakan dalam jaringan, administrasi sistem, aplikasi desktop, dan banyak tempat lainnya. Ini meminjam banyak konsep / fitur dari bahasa lain seperti C, sed, awk, dan lainnya. Substitusi sederhana dapat dilakukan sebagai berikut:
Seperti sed, perl juga memiliki flag -i.
Python
Bahasa ini sangat fleksibel dan juga digunakan dalam berbagai aplikasi. Ini memiliki banyak fungsi untuk bekerja dengan string, di antaranya adalah
replace()
, jadi jika Anda memiliki variabel likevar="Hello World"
, Anda bisa melakukannyavar.replace("Hello","Good Morning")
Cara sederhana untuk membaca file dan mengganti string di dalamnya adalah sebagai berikut:
Namun, dengan Python, Anda juga perlu meng-output ke file baru, yang juga dapat Anda lakukan dari dalam skrip itu sendiri. Misalnya, ini yang sederhana:
Script ini disebut dengan
input.txt
argumen baris perintah. Perintah yang tepat untuk menjalankan skrip python dengan argumen command-line adalahatau
Tentu saja, pastikan itu
./myscript.py
ada di direktori kerja Anda saat ini dan untuk cara pertama, pastikan direktori tersebut dapat dieksekusichmod +x ./myscript.py
Python juga dapat memiliki ekspresi reguler, khususnya, ada
re
modul, yang memilikire.sub()
fungsi, yang dapat digunakan untuk penggantian yang lebih maju.sumber
tr
perintah di unixtr
adalah alat hebat lainnya, tetapi perhatikan bahwa itu untuk mengganti sekumpulan karakter (misalnyatr abc cde
akan diterjemahkana
menjadic
,b
untukd
. Ini sedikit berbeda dari mengganti seluruh kata dengansed
ataupython
Anda dapat menggunakan Vim dalam mode Ex:
%
pilih semua gariss
penggantig
ganti semua instance di setiap barisx
tulis jika telah dilakukan perubahan (sudah) dan keluarsumber
Melalui perintah gsub awk,
Contoh:
Dalam contoh di atas, semua 1 digantikan oleh 0 terlepas dari kolom di mana ia berada.
Jika Anda ingin melakukan penggantian pada kolom tertentu, maka lakukan seperti ini,
Contoh:
Ia menggantikan 1 dengan 0 pada kolom pertama saja.
Melalui Perl,
sumber
inotifywait
bawahsh
env, dan melaporkan data dalam format CSV (karena format khusus bersifat buggy). Saya kemudian menemukan tidak ada cara sederhana untuk menangani dokumen CSV dalam skrip shell ... Dan saya ingin itu sangat ringan. Jadi saya memulai skrip yang cukup sederhana untuk mem-parsing dan melaporkan CSV. Saya membaca spesifikasi CSV dan memperhatikannya lebih rumit dari yang saya harapkan dan mendukung nilai multiline yang dibungkus dengan tanda kutip ganda. Saya mengandalkansed
tokenization tetapi segera menyadari bahwa apa pun yangsed
disebut multilines hingga dua baris. Lalu bagaimana jika salah satu nilai CSV saya menjangkau lebih dari dua baris?sed
adalah s tream ed itor , karena Anda dapat menggunakan|
(pipa) untuk mengirim standar stream (STDIN dan STDOUT khusus) melaluised
dan mengubah mereka pemrograman dengan cepat, membuatnya menjadi alat yang berguna dalam tradisi filsafat Unix; tetapi dapat mengedit file secara langsung juga, menggunakan-i
parameter yang disebutkan di bawah ini.Pertimbangkan yang berikut ini :
s/
digunakan untuk s ubstitute ekspresi ditemukanfew
denganasd
:/g
singkatan "global", artinya melakukan ini untuk seluruh lini. Jika Anda meninggalkan/g
(dengans/few/asd/
, selalu harus ada tiga garis miring tidak peduli apa) danfew
muncul dua kali pada baris yang sama, hanya yang pertamafew
diubah menjadiasd
:Ini berguna dalam beberapa keadaan, seperti mengubah karakter khusus di awal baris (misalnya, mengganti simbol lebih besar dari yang digunakan beberapa orang untuk mengutip materi sebelumnya di utas email dengan tab horizontal sambil meninggalkan ketidaksamaan aljabar yang dikutip kemudian di baris tersebut). tidak tersentuh), tetapi dalam contoh Anda di mana Anda menentukan bahwa di mana saja
few
terjadi itu harus diganti, pastikan Anda memilikinya/g
.Dua opsi berikut (bendera) digabungkan menjadi satu
-ie
,:-i
Pilihan ini digunakan untuk mengedit i n tempat pada file tersebuthello.txt
.-e
Opsi menunjukkan e xpression / perintah untuk dijalankan, dalam hal inis/
.Catatan: Penting bagi Anda
-i -e
untuk mencari / mengganti. Jika ya-ie
, Anda membuat cadangan setiap file dengan huruf 'e' ditambahkan.sumber
Anda bisa melakukan ini:
Contoh: untuk mengganti semua kejadian [logdir ',' '] (tanpa []) dengan [logdir', os.getcwd ()] di semua file yang merupakan hasil dari perintah loc, lakukan:
ex1:
ex2:
di mana [tensorboard / program.py] adalah file untuk dicari
sumber
logdir', ''
->/logdir', os.getcwd()
) membuat jawaban ini sulit untuk diurai. Juga, ada baiknya menentukan bahwa jawaban Anda pertama-tama menemukan file yang akan digunakan, karena itu bukan bagian dari pertanyaan.