GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Mencapai Portabilitas Dengan Sed -i (Pengeditan di Tempat)?

Saya sedang menulis skrip shell untuk server saya, yang merupakan shared hosting yang menjalankan FreeBSD. Saya juga ingin dapat mengujinya secara lokal, di PC saya yang menjalankan Linux. Oleh karena itu, saya mencoba menulisnya dengan cara portabel, tetapi dengan sed Saya tidak melihat cara untuk melakukan itu.

Bagian dari situs web saya menggunakan file HTML statis yang dihasilkan, dan baris sed ini menyisipkan DOCTYPE yang benar setelah setiap regenerasi:

sed -i '1s/^/<!DOCTYPE html> n/' ${file_name.html}

Ia bekerja dengan GNU sed di Linux, tapi FreeBSD sed mengharapkan argumen pertama setelah -i pilihan untuk menjadi ekstensi untuk salinan cadangan. Ini akan terlihat seperti:

sed -i '' '1s/^/<!DOCTYPE html> n/' ${file_name.html}

Namun, GNU sed sebaliknya mengharapkan ekspresi mengikuti segera setelah -i .
(Ini juga memerlukan perbaikan dengan penanganan baris baru, tapi itu sudah dijawab di sini)

Tentu saja saya dapat memasukkan perubahan ini dalam salinan skrip server saya, tetapi itu akan mengacaukan penggunaan VCS saya untuk pembuatan versi. Apakah ada cara untuk mencapai ini dengan sed dengan cara yang sepenuhnya portabel?

Jawaban yang Diterima:

GNU sed menerima ekstensi opsional setelah -i . Ekstensi harus dalam argumen yang sama tanpa spasi. Sintaks ini juga berfungsi pada sed BSD.

sed -i.bak -e '…' SOMEFILE

Perhatikan bahwa pada BSD, -i juga mengubah perilaku ketika ada beberapa file input:mereka diproses secara independen (jadi misalnya $ cocok dengan baris terakhir setiap file). Ini juga tidak akan berfungsi di BusyBox.

Jika Anda tidak ingin menggunakan file cadangan, Anda dapat memeriksa versi sed yang tersedia.

case $(sed --help 2>&1) in
  *GNU*) set sed -i;;
  *) set sed -i '';;
esac
"[email protected]" -e '…' "$file"

Atau sebagai alternatif, untuk menghindari mengganggu parameter posisi, definisikan sebuah fungsi.

case $(sed --help 2>&1) in
  *GNU*) sed_i () { sed -i "[email protected]"; };;
  *) sed_i () { sed -i '' "[email protected]"; };;
esac
sed_i -e '…' "$file"

Jika Anda tidak ingin repot, gunakan Perl.

perl -i -pe '…' "$file"

Jika Anda ingin menulis skrip portabel, jangan gunakan -i — tidak ada di POSIX. Lakukan secara manual apa yang dilakukan sed di balik layar — hanya satu baris kode lagi.

sed -e '…' "$file" >"$file.new"
mv -- "$file.new" "$file"

Linux
  1. Cara Menggunakan Perintah Sed di Linux dengan Contoh

  2. Bagaimana cara menggunakan sed untuk mengubah file konfigurasi saya, dengan kunci dan nilai yang fleksibel?

  3. Cara menghapus \r karakter dengan sed

  1. Bagaimana Cara Mengganti String Dalam File?

  2. Tambahan Dengan 'sed'?

  3. Bagaimana Mengganti String Dengan String Yang Mengandung Slash Dengan Sed?

  1. Bagaimana Cara Menggunakan Sed Atau Ex Untuk Mengganti Blok (Kode multi-baris) Dengan Blok Teks (kode) Baru?

  2. Bagaimana melakukan sed like text ganti dengan python?

  3. Bagaimana cara mengganti tanda kutip tunggal dengan karakter lain di sed?