it-swarm-id.com

Perbedaan antara sed pada Mac OSX dan sed "standar" lainnya?

Saya mengalami beberapa masalah dalam menggunakan jawaban yang disediakan di situs ini untuk pertanyaan ini tentang perintah sed untuk mengganti baris kosong dengan dua baris konten lainnya , dan muncul jika perintah sed pada Mac OS (10.6.7 untuk saya) berbeda. Saya tidak berpikir begitu, tetapi bertanya-tanya apakah orang lain di situs ini berpikir berbeda.

67
Peter Grill

Perilaku utilitas Shell memang berbeda sedikit antara varian unix. Ada banyak varian nix , dengan komplekshistory . Ada paya standardisasi seperti POSIX standar dan supersetnya spesifikasi UNIX tunggal . Sebagian besar sistem saat ini menerapkan POSIX: 2001, juga dikenal sebagai Spesifikasi Tunggal UNIX versi , dengan penyimpangan kecil dan banyak ekstensi. Spesifikasi Single Unix bukan tutorial, tetapi versi 3 dapat dibaca jika Anda sudah memiliki gagasan tentang apa yang dilakukan perintah. Anda dapat berkonsultasi untuk mengetahui apakah beberapa fitur standar atau perpanjangan dari sistem tertentu.

Mayoritas pengguna unix menggunakan Linux dan belum menggunakan varian lain. Linux hadir dengan GNU utilitas, yang sering memiliki banyak ekstensi ke standar. Jadi, Anda akan menemukan cukup banyak kode di luar sana yang berfungsi di Linux tetapi tidak di kesatuan lain, karena bergantung pada ekstensi itu.

Mengenai sed, bacalah spesifikasi sed Unix Tunggal untuk minimum yang seharusnya didukung oleh setiap sistem, halaman manual pada sistem Anda untuk apa yang didukung oleh implementasi Anda, dan - manual sed GN untuk apa yang digunakan kebanyakan orang di luar sana.

Salah satu ekstensi tidak standar dalam GNU sed mendukung beberapa perintah berjalan bersama. Misalnya, ini GNU sed mencetak semua baris yang berisi a, tetapi mengubah b menjadi c pertama:

sed -ne '/a/ {s/b/c/g; p}'

{ Dan } Sebenarnya adalah perintah yang terpisah, jadi untuk portabilitas penuh, Anda perlu menentukannya pada baris yang berbeda (dalam file) atau dalam argumen -e Terpisah (pada garis komando). Tidak adanya pemisah perintah setelah { Dan penggunaan ; Sebagai pemisah perintah adalah ekstensi umum. Tidak adanya pemisah perintah sebelum } Adalah ekstensi yang kurang umum. Ini sesuai standar:

sed -n -e '/a/ {' -e 's/b/c/g' -e p -e '}'

Ini tidak standar tetapi diterima secara umum:

sed -ne '/a/ { s/b/c/g; p; }'

Ekstensi lain yang tidak standar tetapi umum adalah penggunaan \n Yang berarti baris baru dalam teks pengganti s (penggunaan dalam regexp adalah standar). Metode portabel adalah memasukkan backslash-newline dalam skrip sed. Ekstensi umum lainnya adalah \+, \? Dan \| Di regexps berarti satu atau lebih, paling banyak satu dan bergantian; ekspresi reguler dasar portabel tidak memilikinya. Sebagai contoh, perintah pertama adalah cara yang tidak portabel untuk mengganti urutan spasi yang berdekatan dengan baris baru; perintah kedua adalah standar yang sesuai dengan standar.

sed -e 's/ \+/\n/'
sed -e 's/  */\
/'

OS X saat ini hadir dengan sed FreeBSD dari tahun 2005. Sebagian besar perbedaan di bawah ini juga berlaku untuk versi sed BSD lainnya.

OS X sed menggunakan -E untuk ERE dan GNU sed uses -r. -E adalah alias untuk -r in GNU sed (ditambahkan pada 4.2, tidak didokumentasikan hingga 4.3). Versi FreeBSD dan NetBSD yang lebih baru mendukung keduanya -E dan -r. OpenBSD hanya mendukung -E.

-i '' bekerja dengan sed OS X tetapi tidak GNU sed. -i bekerja dengan GNU sed, versi terbaru dari NetBSD, OpenBSD sed, tetapi tidak untuk OS X. -i -e bekerja dengan keduanya tetapi dalam kasus FreeBSD sed membuat cadangan file asli dengan -e ditambahkan ke nama file (dan Anda harus memberikan tidak lebih dari satu ekspresi ke sed).

GNU dan penafsiran urutan melarikan diri seperti \t, \n, \001, \x01, \w, dan \b. OS X dan sed POSIX hanya menafsirkan \n (tetapi tidak di bagian pengganti s).

GNU sed interprets \|, \+, dan \? dalam BRE tetapi sed OS X dan sed POSIX tidak. \(, \), \{, dan \} adalah POSIX BRE.

GNU sed memungkinkan penghapusan ; atau baris baru sebelum } tapi OS X tidak.

i (masukkan), a (tambahkan), dan c (perubahan) harus diikuti oleh garis miring terbalik dan baris baru dalam sed OS X dan sed POSIX tetapi tidak di GNU sed. GNU sed menambahkan baris baru yang hilang setelah teks disisipkan oleh i, a, atau c tetapi sed OS X tidak. Misalnya sed 1ia adalah GNU alternatif untuk sed $'1i\\\na\n'.

Sebagai contoh printf a|sed -n p menambahkan baris baru di sed OS X tetapi tidak di GNU sed.

Sed OS X tidak mendukung I (case-insensitive) atau M (multi-line) pengubah. Versi terbaru FreeBSD dan dukungan I.

Sed OS X tidak mendukung -s (--separate), -u (--unbuffered), atau -z (--null-data).

Satu opsi BSD yang tidak didukung oleh GNU sed is -a, yang membuat w ditambahkan ke file alih-alih memotong file.

Contoh GNU perintah sed yang tidak berfungsi dengan sed OS X:

sed /pattern/,+2d # like `sed '/pattern/{N;N;d;}'`
sed -n 0~3p # like `awk NR%3==0`
sed /pattern/Q # like `awk '/pattern/{exit}1'` or `sed -n '/pattern/,$!p'`
sed 's/\b./\u&/g' # \u converts the next character to uppercase
sed 's/^./\l&/' # \l converts the next character to lowercase
sed -i '1ecat file_to_prepend' file # e executes a Shell command
sed -n l0 # 0 disables wrapping
69
Lri

Cara terbaik yang saya temukan untuk menjalankan skrip yang sama di Linux dan Mac adalah dengan:

sed -i.bak -e 's/foo/bar/' -- "${TARGET}" &&
  rm -- "${TARGET}.bak"
6
vikrantt