Pengeditan di tempat dengan sed pada OS X

142

Saya ingin mengedit file dengan sed pada OS X. Saya menggunakan perintah berikut:

sed 's/oldword/newword/' file.txt

Keluaran dikirim ke terminal. file.txt tidak dimodifikasi. Perubahan disimpan ke file2.txt dengan perintah ini:

sed 's/oldword/newword/' file1.txt > file2.txt

Namun saya tidak ingin file lain. Saya hanya ingin mengedit file1.txt . Bagaimana saya bisa melakukan ini?

Saya sudah mencoba flag -i. Ini menghasilkan kesalahan berikut:

sed: 1: "file1.txt": invalid command code f
Minggu Senin
sumber
2
Apa perintah tepat yang Anda gunakan saat mencoba -ibendera?
eldarerathis

Jawaban:

282

Anda dapat menggunakan -iflag dengan benar dengan memberikan suffix untuk ditambahkan ke file yang dicadangkan. Memperluas contoh Anda:

sed -i.bu 's/oldword/newword/' file1.txt

Akan memberi Anda dua file: satu dengan nama file1.txtyang berisi substitusi, dan satu dengan nama file1.txt.buyang memiliki konten asli.

Agak berbahaya

Jika Anda ingin menimpa file asli secara destruktif, gunakan sesuatu seperti:

sed -i '' 's/oldword/newword/' file1.txt
      ^ note the space

Karena cara garis diuraikan, diperlukan spasi antara flag opsi dan argumennya karena argumennya panjang nol.

Selain mungkin merusak sumber asli Anda, saya tidak mengetahui ada bahaya lebih lanjut dari menipu dengan cara ini. Namun perlu dicatat bahwa jika permohonan sedini merupakan bagian dari skrip, The Unix Way ™ akan menggunakan ( sednon-destruktif), menguji apakah itu keluar dengan bersih, dan hanya kemudian menghapus file asing.

mengurangi
sumber
Anda benar saya menghilangkan ekstensi setelah bendera -i. Apakah -i''berbahaya karena alasan apa pun selain berpotensi mengacaukan file asli (dan tidak memiliki cadangan)?
SundayMonday
Menurut sedhalaman manual jika Anda kehabisan ruang disk pada perangkat Anda dapat merusak file saat sedang berjalan dan memiliki hasil output yang buruk. Jika Anda bekerja di bawah kendali sumber lokal sed -i ""tanpa cadangan, sebagian besar waktu akan baik-baik saja (atau sesaat git init && git add -A . && git commit -m 'backup'sebelum menjalankan -imode sed ).
cfeduke
2
Saya menemukan sedikit agak berbahaya sangat berguna. +1
Andre
5
BSD sed mensyaratkan bahwa tidak ada ruang setelah flag -i. Jadi, -i''ini valid, tetapi -i ''tidak.
Todd A. Jacobs
3
Argh! BSD sed mengabaikan karakter '\ n' dan mencetak 'n' sebagai gantinya! Saya hanya akan mengganti BSD sed dengan GNU sed di mac saya!
nterry
20

Saya punya masalah serupa dengan MacOS

sed -i '' 's/oldword/newword/' file1.txt

tidak berhasil, tapi

sed -i"any_symbol" 's/oldword/newword/' file1.txt

bekerja dengan baik.

ksnt
sumber
Ini sekarang sebaliknya. sed -i '' <file>bekerja tetapi sed -i'' <file>tidak lagi berfungsi
Zohaib Amanzai
7
sed -i -- "s/https/http/g" file.txt
jazzed
sumber
4

Anda dapat menggunakan -i''( --in-place) untuk sedseperti yang disarankan. Lihat: The -idi tempat argumen , namun perhatikan bahwa -ipilihan adalah ekstensi FreeBSD non-standar dan mungkin tidak tersedia pada sistem operasi lain. Kedua sedadalah S tream ED itor, bukan file editor .


Cara alternatif adalah dengan menggunakan substitusi bawaan dalam mode Vim Ex, seperti:

$ ex +%s/foo/bar/g -scwq file.txt

dan untuk banyak file:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.*

Untuk mengedit semua file secara rekursif, Anda dapat menggunakan **/*.*jika shell mendukungnya (diaktifkan oleh shopt -s globstar).


Cara lain adalah dengan menggunakan gawkdan ekstensi "inplace" yang baru seperti:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1
kenorb
sumber
4

Ini menciptakan file cadangan. Misalnya sed -i -e 's/hello/hello world/' testfileuntuk saya, buat file cadangan, testfile-e, di dir yang sama.

JustADude
sumber
Sama di sini dengan Mac OS Catalina. Melewati kedua -i dan -e secara terpisah (TIDAK -selama!) Membuat file cadangan dengan '-e' ditambahkan.
Daniel Kesner
1

Kamu bisa memakai:

sed -i -e 's/<string-to-find>/<string-to-replace>/' <your-file-path>

Contoh:

sed -i -e 's/Hello/Bye/' file.txt

Ini berfungsi sempurna di Mac .

Vincent Lal
sumber
2
Ini membuat file cadangan untuk saya di Mac OS Catalina dengan '-e' ditambahkan.
Daniel Kesner
Ini salah untuk macOS. Silakan lihat halaman "man sed" di sana. -imembutuhkan argumen untuk macOS. Karena Anda tidak menentukan satu, itu menggunakan -e, yang menghasilkan memiliki file kedua dengan -editambahkan. -etidak ada di macOS, itu -E. Jadi perintah yang benar untuk macOS adalahsed -i '' -E 's/Hello/Bye/' file.txt
Marc J. Schmidt