Saya ingin menjalankan pencarian dan mengganti file HTML melalui baris perintah.
Perintah saya terlihat seperti ini:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html
Ketika saya menjalankan ini dan melihat file sesudahnya, itu kosong. Itu menghapus isi file saya.
Ketika saya menjalankan ini setelah mengembalikan file lagi:
sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Ini stdout
adalah isi file, dan menemukan dan mengganti telah dieksekusi.
Mengapa ini terjadi?
shell
unix
sed
io-redirection
BBales
sumber
sumber
perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html
sed
perintah terkait untuk menemukan string dan mengganti seluruh baris: stackoverflow.com/questions/11245144/…Jawaban:
Ketika shell melihat
> index.html
di baris perintah itu membuka fileindex.html
untuk menulis , menghapus semua konten sebelumnya.Untuk memperbaikinya, Anda perlu memberikan
-i
opsi untuksed
membuat perubahan sebaris dan membuat cadangan file asli sebelum melakukan perubahan di tempat:Tanpa .bak perintah akan gagal pada beberapa platform, seperti Mac OSX.
sumber
truncates the file
bukannyaopens the file
mungkin membuatnya lebih jelas.sed -i '' 's/blah/xx/g'
.bak
setelah inised -i
?Alternatif, berguna, polanya adalah:
Itu memiliki banyak efek yang sama, tanpa menggunakan
-i
opsi, dan juga berarti bahwa, jika skrip sed gagal karena suatu alasan, file input tidak musnah. Selanjutnya, jika pengeditan berhasil, tidak ada file cadangan yang tertinggal. Idioma semacam ini dapat berguna di Makefiles.Cukup banyak sed yang memiliki
-i
pilihan, tetapi tidak semuanya; sed posix adalah salah satu yang tidak. Jika Anda menginginkan portabilitas, maka sebaiknya dihindari.sumber
... && mv index.html{.tmp,}
sh
(jika saya ingat dengan benar) tidak memiliki{...}
ekspansi itu. Dalam Makefile Anda mungkin menggunakansh
daripadabash
, jadi jika Anda bertujuan untuk portabilitas (atau kemungkinan) maka Anda harus menghindari konstruksi itu.Ini melakukan substitusi global di tempat pada file index.html. Mengutip string mencegah masalah dengan spasi putih dalam permintaan dan penggantian.
sumber
gunakan opsi sed's -i, mis
sumber
's/STRING_TO_REPLACE/REPLACE_WITH/g'
-i
melakukan pengeditan di tempat file , jadi tidak masuk akal untuk menggabungkannya dengan input stdin .Untuk mengubah banyak file (dan menyimpan cadangan masing-masing sebagai * .bak):
akan mengambil semua file dalam direktori dan menggantinya
|
denganx
ini disebut "Perl pie" (semudah pie)sumber
sed
sebagai persyaratan, hanya menggunakannya sebagai alat yang sudah dicoba.Anda harus mencoba menggunakan opsi
-i
untuk mengedit di tempat.sumber
Jika Anda memiliki tautan untuk ditambahkan, coba ini. Cari URL seperti di atas (dimulai dengan https dan berakhir dengan.com di sini) dan ganti dengan string URL. Saya telah menggunakan variabel di
$pub_url
sini.s
di sini berarti pencarian dang
berarti penggantian global.Berhasil !
sumber
Peringatan: ini adalah metode yang berbahaya! Itu menyalahgunakan buffer i / o di linux dan dengan opsi spesifik buffering berhasil bekerja pada file kecil. Ini merupakan keingintahuan yang menarik. Tetapi jangan menggunakannya untuk situasi nyata!
Selain
-i
opsised
Anda dapat menggunakantee
utilitas .Dari
man
:Jadi, solusinya adalah:
- di sini
tee
diulang untuk memastikan bahwa pipa disangga. Kemudian semua perintah dalam pipa diblokir sampai mereka mendapatkan beberapa input untuk bekerja. Setiap perintah dalam pipa dimulai ketika perintah hulu telah menulis 1 buffer byte (ukurannya ditentukan di suatu tempat ) ke input perintah. Jadi perintah terakhirtee index.html
, yang membuka file untuk ditulis dan oleh karena itu mengosongkannya, berjalan setelah pipa upstream selesai dan output berada di buffer dalam pipa.Kemungkinan besar yang berikut ini tidak akan berfungsi:
- itu akan menjalankan kedua perintah pipa pada saat yang sama tanpa ada pemblokiran. (Tanpa menghalangi pipa harus melewati garis byte dengan baris bukan buffer oleh penyangga. Sama seperti ketika Anda menjalankan
cat | sed s/bar/GGG/
. Tanpa menghalangi itu lebih interaktif dan biasanya pipa dari hanya 2 perintah berjalan tanpa buffering dan menghalangi. Pipa yang lebih panjang akan buffered.) Thetee index.html
kehendak buka file untuk ditulis dan itu akan dikosongkan. Namun, jika Anda selalu mengaktifkan buffering, versi kedua juga akan berfungsi.sumber
>
, tetapi intinya adalah bahwa ini adalah solusi rusak yang kemungkinan menyebabkan hilangnya data).Masalah dengan perintah
adalah yang
file
dipotong oleh shell sebelum sed benar-benar bisa memprosesnya. Akibatnya, Anda mendapatkan file kosong.Cara sed untuk melakukan ini adalah menggunakan
-i
untuk mengedit di tempat, seperti yang disarankan jawaban lain. Namun, ini tidak selalu seperti yang Anda inginkan.-i
akan membuat file sementara yang kemudian akan digunakan untuk mengganti file asli. Ini bermasalah jika file asli Anda adalah tautan (tautan akan diganti dengan file biasa). Jika Anda perlu menyimpan tautan, Anda dapat menggunakan variabel sementara untuk menyimpan hasil sed sebelum menulis kembali ke file, seperti ini:Lebih baik lagi, gunakan
printf
daripadaecho
karenaecho
kemungkinan akan diproses\\
seperti\
pada beberapa shell (misalnya tanda hubung):sumber
sed 'code' file > file.tmp; cat file.tmp > file; rm file.tmp
Dan
ed
jawabannya:Untuk mengulangi apa yang dijawab oleh codaddict , shell menangani pengalihan terlebih dahulu , menghapus file "input.html", dan kemudian shell memanggil perintah "sed" meneruskannya dengan file yang sekarang kosong.
sumber
ed
versi"sed
jawaban? apakah kinerjanya lebih cepat?sed
tidak menerapkan-i
untuk mengedit di tempat.ed
ada di mana-mana dan tidak memungkinkan Anda menyimpan suntingan ke file asli. Plus, selalu baik untuk memiliki banyak alat dalam kit Anda.Anda dapat menggunakan Vim dalam mode Ex:
%
pilih semua barisx
Simpan dan tutupsumber
Saya sedang mencari opsi di mana saya dapat menentukan rentang garis dan menemukan jawabannya. Misalnya saya ingin mengganti host1 ke host2 dari baris 36-57.
Anda dapat menggunakan opsi gi juga untuk mengabaikan huruf besar-kecil.
sumber
Dengan segala hormat terhadap jawaban yang benar di atas, itu selalu merupakan ide yang baik untuk "keringkan" skrip seperti itu, sehingga Anda tidak merusak file Anda dan harus memulai lagi dari awal.
Dapatkan saja skrip Anda untuk menumpahkan output ke baris perintah alih-alih menulisnya ke file, misalnya, seperti itu:
ATAU
Dengan cara ini Anda dapat melihat dan memeriksa output dari perintah tanpa file Anda terpotong.
sumber