Saya mencoba mengubah satu kata pada baris tertentu dalam sebuah file, tetapi saya mengalami masalah saat menghubungkan semuanya.
Pada dasarnya, pada satu baris di file saya ada kata kunci 'firmware_revision', dan pada baris ini (dan hanya baris ini) saya ingin mengganti kata 'test' dengan kata 'production'.
Jadi saya bisa melakukan ini:
grep 'firmware_revision' myfile.py | sed 's/test/production'
Ini akan memilih baris yang saya inginkan dan melakukan substitusi, tetapi saya tidak tahu cara memasukkan baris baru ini ke file asli untuk mengganti baris yang lama. Saya jelas tidak bisa hanya mengarahkannya kembali ke file, jadi apa yang harus saya lakukan?
Bahkan jika saya menggunakan temporaries, dengan menggunakan grep
hanya untuk mendapatkan baris saya perlu saya kehilangan semua data lain dalam file, jadi saya tidak bisa lagi mengarahkan semua itu ke file temp kemudian ganti yang asli dengan temp.
Sunting - Seseorang meminta informasi lebih lanjut
Katakanlah saya punya file yang penuh dengan baris seperti ini
[
('key_name1', str, 'value1', 'Description'),
('key_name2', str, 'value2', 'Description'),
('key_name3', str, 'value3', 'Description'),
('firmware_revision', str, 'my-firmware-name-test', 'Firmware revision name')
]
sekarang saya ingin menulis skrip (idealnya satu baris) yang akan menemukan baris yang berisi 'firmware_revision', dan mengubah semua contoh kata 'tes' pada baris itu menjadi 'produksi'. Kata 'test' mungkin ada di tempat lain di file itu dan saya tidak ingin itu diubah. Jadi untuk menjadi jelas, saya ingin mengubah baris di atas menjadi
('firmware_revision', str, 'my-firmware-name-production', 'Firmware revision name')
Bagaimana saya melakukan ini?
sumber
sed
sangat kuat, ia dapat melakukan kedua fungsi (grep
dan substitusi) tetapi kami akan memerlukan lebih banyak info tentang bagaimana garis terlihat untuk membantu Anda.sed -i.bak '/firmware_revision/ s/test/production/' myfile.py
Jawaban:
Mencoba:
Di sini,
/firmware_revision/
bertindak sebagai syarat. Memang benar untuk baris yang cocok dengan regexfirmware_revision
dan false untuk baris lainnya. Jika kondisinya benar, maka perintah berikut dijalankan. Dalam hal ini, perintah itu adalah perintah pengganti yang menggantikan kejadian pertamatest
denganproduction
.Dengan kata lain, perintah
s/test/production/
dieksekusi hanya pada baris yang cocok dengan regexfirmware_revision
. Semua garis lainnya melewati tidak berubah.Secara default, sed mengirimkan outputnya ke standard out. Namun, Anda ingin mengubah file di tempatnya. Jadi, kami menambahkan
-i
opsi. Secara khusus,-i.bak
menyebabkan file diubah di tempat dengan salinan cadangan disimpan dengan.bak
ekstensi.Jika Anda telah memutuskan bahwa perintah itu berfungsi untuk Anda dan Anda ingin hidup dalam bahaya dan tidak membuat cadangan, maka, dengan GNU sed (Linux), gunakan:
Sebaliknya, pada BSD (OSX),
-i
opsi harus memiliki argumen. Jika Anda tidak ingin menyimpan cadangan, berikan argumen kosong. Jadi, gunakan:Edit
Dalam pengeditan pertanyaan, OP meminta setiap kemunculan
test
di telepon untuk digantiproduction
. Dalam hal itu, kami menambahkang
opsi ke perintah pengganti untuk pengganti global (untuk jalur itu):sumber
-i.bak
bagian itu juga.-i
ditambahkan.sed
dapat dilakukan ...''
setelah yang pertama-i
?sed -i '/firmware_revision/ s/test/production/g' myfile.py
jika tidak, hanya instance pertama yang diubah.Pada komputer lama dengan old-school
sed
yang tidak mendukung opsi-i
:sumber
ed
dan melakukannya dalam satu baris:printf %s\\n g/firmware_revision/s/test/production/g w q | ed -s myfile.py
ed(1)
tidak menawarkan alasan untuk menunjukkan penggunaanmktemp(1)
.ed
halnya. Alih-alihmv -f "$TF" myfile.pl
, gunakancat "$TF" > myfile.pl && rm -f "$TF"
. BTW, itu praktik yang baik untuk menggunakan nama variabel huruf kecil ($tf
bukan$TF
), mereka dijamin tidak akan bertentangan dengan bash built-in vars (mungkin shell bourne lainnya juga).cat "$TF" > myfile.pl
coba ini:touch a b; chmod 0444 a; cat b >a
(BTW,sed -i
tidak akan berfungsi dalam kasus itu, baik). Lebih baik biarkan pengguna berurusan dengan itu. Re::rm -f "$TF"
tidak diperlukan, lihattrap ... EXIT
. Re:$tf
bukannya$TF
: mungkin; ini masalah gaya.umask
berbeda dari perms asli. Adapun vars huruf besar, itu bukan hanya masalah gaya - banyak orang yang telah membuat kesalahan dengan menggunakan PATH huruf besar atau ACAK atau SHELL atau apa pun untuk variabel mereka sendiri telah menemukan cara yang sulit. (dan ya, saya sering menggunakan huruf besar sendiri. Saya tahu itu salah, saya mencoba untuk menghentikan kebiasaan itu).