Jadi saya telah menggunakan 'sed' di linux untuk sementara waktu, tetapi telah mengalami sedikit kesulitan mencoba menggunakannya di OSX sejak 'POSIX sed' dan 'GNU sed' memiliki banyak perbedaan kecil. Saat ini saya sedang berjuang dengan cara memasukkan satu baris teks setelah nomor baris tertentu. (dalam hal ini, baris 4)
Di linux saya akan melakukan sesuatu seperti ini:
sed --in-place "4 a\ mode '0755'" file.txt
Jadi pada OSX saya mencoba ini:
sed -i "" "4 a\ mode '0755'" file.txt
Namun ini terus memberi saya kesalahan 'karakter tambahan setelah \ di akhir perintah'. Ada ide apa yang salah di sini? Apakah saya salah ketik? Atau apakah saya tidak mengerti perbedaan lain antara versi sed?
Jawaban:
Sebenarnya, spesifikasi POSIX untuk
sed
memerlukan baris baru setelaha\
:Hal ini membuat menulis satu kalimat sedikit rasa sakit, yang mungkin merupakan alasan berikut ekstensi GNU ke
a
,i
danc
perintah:Jadi, untuk menjadi portabel dengan
sed
sintaks Anda, Anda harus menyertakan baris baru setelaha\
entah bagaimana. Cara termudah adalah dengan hanya memasukkan baris baru yang dikutip:(di mana
$
dan>
apakah shell meminta). Jika Anda merasa sakit,bash
[1] memiliki$' '
sintaks kutipan untuk menyisipkan lolos gaya-C, jadi gunakan saja[1] dan mksh (r39b +) dan beberapa shell bourne non-bash (mis., / Bin / sh dalam FreeBSD 9+)
sumber
Seperti yang dijelaskan dalam jawaban ini , akan sangat membantu ketika menggunakan perintah sed seperti
i
dana
menggunakan beberapa-e "..."
klausa. Masing-masing klausa ini akan dipahami dipisahkan oleh baris baru. Thei
dana
perintah sulit untuk digunakan dalam inline sed script sebaliknya (mereka dirancang untuk digunakan dalam multiline sed file script dipanggil menggunakansed -f file ...
). Sepertinya Anda tidak dapat menggunakan baris baru tersirat yang diperkenalkan pada akhir-e
klausa untuk memisahkana\
dan baris teks yang akan ditambahkan. Tetapi Anda dapat menggunakannya untuk mengakhiri baris teks yang akan ditambahkan.Dalam kasus khusus ini, apa yang Anda coba lakukan sebenarnya bisa diselesaikan dengan satu
-e ...
klausa. Anda hanya perlu menggunakana
perintah dengan benar. Dengan standar POSIX,a
perlu diikuti oleh\
, maka yang perlu diikuti oleh baris baru, maka sisa baris berikutnya akan dimasukkan (sampai baris baru atau akhir-e
klausa ditemui). Jadi Anda bisa melakukan:sumber
GNU sed tampaknya jauh lebih umum digunakan daripada POSIX, berdasarkan contoh / tutorial yang saya gunakan.
Saya telah menemukan bahwa jauh lebih mudah hanya menginstal sed GNU pada mesin OSX apa pun yang saya gunakan. Jika Anda tertarik, cara terbaik untuk melakukannya adalah menginstalnya melalui Homebrew .
Anda bisa saja
$ brew install gnu-sed
, atau mendapatkan semua utilitas umum GNU$ brew install coreutils
.Kemudian ketika Anda mengalami masalah sintaks dengan
date
atau beberapa program lain, Anda bisa menggunakan versi GNU. Akhirnya saya memutuskan lebih mudah untuk selalu menggunakan versi GNU dan menempatkannya lebih awal dari versi sistem di WindowsPATH
.sumber
Perl tidak menderita dari keanehan yang tergantung pada platform seperti GNU vs. non-GNU vs. "eksklusif". Anda bisa melakukannya:
The
-n' option creates a loop that reads every line of the input file. Unlike its cousin
-p(not used here) it doesn't automatically print every line read. The
-iinvokes in-place replacement. The argument to
-i(viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e
sinyal awal dari script.Yang
$.
menunjukkan nomor baris, dimulai dengan baris-1. Dengan demikian baris perintah membaca 'file' dan ketika nomor baris sama dengan 4, itu mencetak baris yang diikuti oleh apa pun yang Anda ingin menyuntikkan.Saya akan segera menambahkan bahwa Perl berakar pada akarnya
sed
, AWK dan C, jadi sintaksis untuk substitusi sederhana, dll. Bukan kurva belajar yang sangat curam.sumber
perl -wlpi.old -e 'print "mode 0755" if $. == 5' file.txt
. The-p
beralih bekerja baik di sini (karena kita ingin mencetak setiap baris); kita hanya perlu mengubah logika dari "mencetak setelah baris 4" menjadi "mencetak sebelum baris 5". Dan-l
saklar membuatnya sehingga "\ n" dicetak secara otomatis dengan setiapprint
, sehingga Anda tidak perlu mencetaknya sendiri.