Saya mencoba mencari tahu apakah mungkin untuk mengedit file dalam perintah sed tunggal tanpa secara manual mengalirkan konten yang diedit ke file baru dan kemudian mengubah nama file baru ke nama file asli. Saya mencoba -i
opsi tetapi sistem Solaris saya mengatakan itu -i
adalah opsi ilegal. Apakah ada cara yang berbeda?
300
-i
adalah pilihan di gnu sed, tetapi tidak dalam sed standar. Namun, itu mengalirkan konten ke file baru dan kemudian mengganti nama file sehingga bukan yang Anda inginkan.Jawaban:
The
-i
pilihan stream konten diedit ke dalam sebuah file baru dan kemudian mengganti nama belakang layar, anyway.Contoh:
dan
pada MacOS .
sumber
sed -i "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>
Pada sistem di mana
sed
tidak memiliki kemampuan untuk mengedit file di tempat, saya pikir solusi yang lebih baik adalah menggunakanperl
:Meskipun ini memang membuat file sementara, ini menggantikan yang asli karena sufiks / ekstensi kosong telah disediakan.
sumber
sudo
. Dalam pikiran saya, pertanyaannya adalah tentang bagaimana menghindari membuat dan mengganti nama file sementara secara manual tanpa harus menginstal GNU atau BSD terbarused
. Cukup gunakan Perl.sed 's/foo/bar/g' file.txt > file.tmp && mv file.tmp file.txt
,. Hanya karena pengeditan di tempat melakukan penggantian nama menggunakan file sementara, tidak berarti ia harus melakukan pengubahan nama secara manual ketika opsi tidak tersedia. Ada alat lain di luar sana yang dapat melakukan apa yang dia inginkan, dan Perl adalah pilihan yang jelas. Bagaimana ini bukan jawaban untuk pertanyaan awal?sed
. Pertanyaan itu sebenarnya sangat bagus, tetapi nilainya telah berkurang oleh orang-orang yang tidak dapat membaca halaman manual atau tidak dapat diganggu untuk benar - benar membaca pertanyaan di SO.Perhatikan bahwa pada OS X Anda mungkin mendapatkan kesalahan aneh seperti "kode perintah tidak valid" atau kesalahan aneh lainnya saat menjalankan perintah ini. Untuk memperbaiki masalah ini coba
Ini karena pada versi OSX
sed
,-i
opsi mengharapkanextension
argumen sehingga perintah Anda sebenarnya diuraikan sebagaiextension
argumen dan jalur file ditafsirkan sebagai kode perintah. Sumber: https://stackoverflow.com/a/19457213sumber
brew install gnu-sed
bersama denganPATH
akan memungkinkan Anda untuk menggunakan versi sed GNU. Terima kasih telah menyebutkan; penggaruk kepala yang pasti.Berikut ini berfungsi dengan baik di mac saya
Kami mengganti foo dengan bar di file sampel. Cadangan file asli akan disimpan di sample.bak
Untuk mengedit inline tanpa cadangan, gunakan perintah berikut
sumber
Satu hal yang perlu diperhatikan,
sed
tidak dapat menulis file sendiri sebagai satu-satunya tujuan sed adalah untuk bertindak sebagai editor pada "aliran" (yaitu pipa stdin, stdout, stderr, dan>&n
buffer lain , soket dan sejenisnya). Dengan mengingat hal ini, Anda dapat menggunakan perintah laintee
untuk menulis output kembali ke file. Pilihan lain adalah membuat tambalan dari menyalurkan konten ke dalamnyadiff
.Metode tee
Metode tambalan
MEMPERBARUI:
Juga, perhatikan bahwa tambalan akan membuat file berubah dari baris 1 dari output diff:
Tambalan tidak perlu tahu file mana yang akan diakses karena ini ditemukan di baris pertama dari keluaran dari diff:
sumber
/dev/stdin 2014-03-15
, jawab 7 Jan - apakah Anda seorang penjelajah waktu?/dev/stdin
tidak ada, jadi Anda harus mengganti/dev/stdin
dengan '-', tanda hubung tunggal tanpa tanda kutip, jadi perintah berikut ini akan berfungsi:$ sed 's/oo/u/' fubar | diff -p fubar -
dan$ sed 's/oo/u/' fubar | diff -p fubar - | patch
patch
tidak akan terpotong juga. Saya pikir menyimpan output ke file lain dan kemudiancat
ke asli akan lebih aman.Tidak mungkin melakukan apa yang Anda inginkan
sed
. Bahkan versised
yang mendukung-i
opsi untuk mengedit file di tempat melakukan persis apa yang Anda secara eksplisit menyatakan tidak Anda inginkan: mereka menulis ke file sementara dan kemudian mengganti nama file. Tapi mungkin Anda bisa menggunakannyaed
. Misalnya, untuk mengubah semua kemunculanfoo
kebar
dalam filefile.txt
, Anda dapat melakukan:Sintaks mirip dengan
sed
, tetapi tentu saja tidak persis sama.Tapi mungkin Anda harus mempertimbangkan mengapa Anda tidak ingin menggunakan file sementara berganti nama. Bahkan jika Anda tidak memiliki
-i
pendukungsed
, Anda dapat dengan mudah menulis skrip untuk melakukan pekerjaan untuk Anda. Alih-alihsed -i 's/foo/bar/g' file
, Anda bisa melakukannyainline file sed 's/foo/bar/g'
. Skrip seperti itu sepele untuk ditulis. Sebagai contoh:harus memadai untuk sebagian besar kegunaan.
sumber
inline
dan memohon seperti yang dijelaskan di atas:inline inputfile sed 's/foo/bar/g'
ed
hanya jawaban yang benar-benar ada di tempat. Pertama kali saya butuhkaned
. Terima kasih. Sedikit optimasi adalah dengan menggunakanecho -e ",s/foo/bar/g\012 w"
atauecho $',s/foo/bar/g\012 w'
jika shell memungkinkannya menghindaritr
panggilan ekstra .ed
tidak benar-benar melakukan modifikasi di tempat. Daristrace
output, GNUed
membuat file temp, menulis perubahan ke file temp, kemudian menulis ulang seluruh file asli, menjaga tautan keras. Daritruss
output, Solaris 11ed
juga menggunakan file temp, tetapi mengganti nama file temp ke nama file asli setelah disimpan denganw
perintah, menghancurkan semua tautan keras.ed
dikirimkan dengan makro saat ini (Mojave, apa pun arti jargon pemasarannya) masih mempertahankan hardlink. YMMVAnda bisa menggunakan vi
sumber
sed mendukung pengeditan di tempat. Dari
man sed
:Contoh :
Katakanlah Anda memiliki file
hello.txt
dengan teks:Jika Anda ingin menyimpan cadangan file lama, gunakan:
Anda akan mendapatkan dua file:
hello.txt
dengan konten:dan
hello.txt.bak
dengan konten lama.Jika Anda tidak ingin menyimpan salinan, jangan lewati parameter ekstensi.
sumber
Anda tidak menentukan shell apa yang Anda gunakan, tetapi dengan zsh Anda bisa menggunakan
=( )
konstruk untuk mencapai ini. Sesuatu di sepanjang garis:=( )
mirip dengan>( )
tetapi membuat file sementara yang secara otomatis dihapus ketikacp
berakhir.sumber
Seharusnya menjaga semua hardlink, karena output diarahkan kembali untuk menimpa isi file asli, dan menghindari segala kebutuhan untuk versi sed khusus.
sumber
Jika Anda mengganti jumlah karakter yang sama dan setelah membaca dengan saksama "Di-tempat" mengedit file ...
Anda juga dapat menggunakan operator pengalihan
<>
untuk membuka file untuk membaca dan menulis:Lihat langsung:
Dari Manual Referensi Bash → 3.6.10 Membuka Deskriptor File untuk Membaca dan Menulis :
sumber
Seperti yang dikatakan Moneypenny di Skyfall: "Terkadang cara lama adalah yang terbaik." Kincade mengatakan sesuatu yang serupa di kemudian hari.
Selamat mengedit di tempat. Menambahkan '\ nw \ n' untuk menulis file. Permintaan maaf untuk keterlambatan menjawab permintaan.
sumber
|
. @MattMontag\n
. [range] s / <old> / <new> / <flag> adalah bentuk perintah pengganti - sebuah paradigma yang masih terlihat di banyak editor teks lainnya (oke, vim, turunan langsung dari ed). Bagaimanapun,g
bendera adalah singkatan dari "global", dan berarti "Setiap contoh di setiap baris yang Anda lihat". Rentang3,5
terlihat pada garis 3-5.,5
melihat StartOfFile-5,3,
melihat garis 3-EndOfFile dan,
melihat StartOfFile-EndOfFile. Perintah pengganti global di setiap baris yang menggantikan "false" dengan "true". Kemudian, perintah tulisw
,, dimasukkan.Contoh yang sangat bagus. Saya memiliki tantangan untuk mengedit banyak file dan opsi -i tampaknya menjadi satu-satunya solusi yang masuk akal menggunakannya dalam perintah find. Di sini skrip untuk menambahkan "versi:" di depan baris pertama setiap file:
sumber