Cara normal untuk melakukan ini adalah menggunakan garis miring, tetapi itu mungkin menjadi rumit jika Anda mencari dan mengganti sesuatu dengan garis miring. Itu tidak terjadi di sini, jadi meskipun itu baik-baik saja itu membingungkan pemelihara masa depan seperti Anda.
Thorbjørn Ravn Andersen
2
... dan membimbing mereka untuk mempelajari sesuatu yang baru tentang sedcara ini! :)
hidangan penutup
Jawaban:
15
Sebagai tambahan, perintah pengganti biasanya ditulis sebagai s/pattern/replacement/options. Namun, itu tidak perlu digunakan /- Anda dapat menggunakan karakter lain jika nyaman, jadi bisa jadi s@pattern@replacement@optionsatau s:foo:bar:g. s@+@ @gseperti s/+/ /g- ganti semua +dengan spasi. Demikian pula s@%@\\x@gmenggantikan semua %dengan \x(backslash tunggal adalah karakter pelarian di sed, jadi Anda perlu dua untuk mendapatkan backslash yang sebenarnya).
String seperti foo+%2Fbarakan menjadi foo \x2Fbar. printf "%b"akan memperluas urutan backslash-escaped seperti \x2F(karakter ASCII yang nilai heksadesimalnya 2F, yaitu /) untuk akhirnya memberi Anda foo /bar.
Anda mungkin lebih terbiasa melihatnya dengan /daripada @sebagai pemisah, yang bisa dengan mudah dilakukan di sini tanpa kerumitan karena tidak /muncul dalam pola pencarian maupun teks pengganti. Perintah ini setara:
sed 's/+/ /g;s/%/\\x/g'
Seperti /, @adalah karakter tanda baca yang sangat baik untuk sed.
Di setiap baris input:
s@+@ @g( s/+/ /g) Mengganti ( s) kemunculan +dengan spasi. Ini memengaruhi semua +es pada baris ( g), bukan hanya yang pertama.
; mengakhiri aksi ("perintah") dan memungkinkan Anda menentukan yang lain di "skrip" yang sama.
s@%@\\x@g( s/%/\\x/g) pengganti ( s) kejadian %dengan \x. Seperti sebelumnya, ini bertindak pada semua, bukan hanya yang pertama dari setiap baris ( g).
Di \\xdalam \\hanya mewakili satu \karena \memiliki arti khusus untuk sed. Arti istimewanya sebenarnya adalah sebagai karakter yang Anda gunakan untuk menghilangkan makna khusus dari karakter lain yang muncul setelahnya yang seharusnya memiliki makna khusus. Jadi harus diloloskan sebagai \\.
Sekarang mari kita lihat xargsperintah, yang tujuannya dijalankan printf.
xargsmembangun baris perintah. Jika Anda menjalankan , di mana satu kata atau lebih, berjalan dengan argumen baris perintah tambahan yang dibaca dari inputnya. Dalam hal ini, input ke adalah output dari , karena pipa ( ). Biasanya menginterpretasikan spasi putih apa pun dalam inputnya untuk berarti bahwa teks sebelum dan sesudahnya merupakan argumen yang terpisah, tetapi opsi membuatnya memecah argumen pada kemunculan karakter nol sebagai gantinya.xargs command...command...xargscommand...xargssed|xargs-0
Dalam penggunaan perintah yang dimaksudkan, karakter nol tidak akan muncul dan xargsakan berjalan printf %bhanya dengan satu argumen baris perintah tambahan, output dari sedperintah. Dengan demikian, meskipun tidak setara secara umum, dalam hal ini seluruh pipa mungkin telah ditulis seperti ini menggunakan substitusi perintah alih-alih xargs:
printf '%b\n'"$(sed 's/+/ /g;s/%/\\x/g')"
Adapun apa printfyang dimaksudkan untuk dilakukan di sini, seperti Muru mengatakan yang %bmengkonsumsi Format specifier dan mencetak argumen (seperti %s) tapi menyebabkan lolos backslash - dari jenis yang sedperintah di sisi kiri pipa ditulis untuk menghasilkan - untuk diterjemahkan ke dalam karakter yang mereka wakili .
Misalkan saya menjalankan perintah itu dan lulus http://foldoc.org/debugging%20by%20printfsebagai input. Saya mendapatkan http://foldoc.org/debugging by printfsebagai output, karena %20urutan diterjemahkan ke dalam spasi.
Itulah keindahannya sed , itu berlaku paradigma untuk dirinya sendiri ... Setelah perintah (seperti satau tratau tidak), karakter berikutnya dianggap pemisah.
Anda harus memilih dengan bijak untuk menghindari gangguan pada shell dan perintah itu sendiri, dan menjaga hal itu mudah dibaca, tetapi sangat valid untuk menulis sesuatu yang mengerikan seperti:
echo 'arrival' | sed srarbrg
... dan dapatkan brrivbl hasilnya, itulah yang Anda harapkan. Anda bisa bersenang-senang membuatnya benar-benar samar, seperti di:
echo 'arrival' | sed s\fa\fb\fg # \f is form feed, chr(12)
Penggunaan umum adalah menggunakan slash sebagai pembatas, tetapi ketika ekspresi Anda mengandung pembatas, itu membuatnya lebih mudah untuk mengambil maksudnya. Pembatas Anda bisa berupa apa saja dalam rentang ASCII8 (pembatas multibyte seperti £memancing kesalahan).
Ingat saja tujuannya adalah untuk membuat segalanya lebih mudah, tidak lebih samar.
Berjalan dengan ide samar, ini adalah perintah sed yang valid, meskipun itu tidak melakukan apa pun yang berguna:sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
wjandrea
Bagus! Ya, Anda dapat menggunakan sedperintah sebagai permainan asah otak juga, seberapa serakah itu?
sed
cara ini! :)Jawaban:
Sebagai tambahan, perintah pengganti biasanya ditulis sebagai
s/pattern/replacement/options
. Namun, itu tidak perlu digunakan/
- Anda dapat menggunakan karakter lain jika nyaman, jadi bisa jadis@pattern@replacement@options
ataus:foo:bar:g
.s@+@ @g
sepertis/+/ /g
- ganti semua+
dengan spasi. Demikian pulas@%@\\x@g
menggantikan semua%
dengan\x
(backslash tunggal adalah karakter pelarian di sed, jadi Anda perlu dua untuk mendapatkan backslash yang sebenarnya).String seperti
foo+%2Fbar
akan menjadifoo \x2Fbar
.printf "%b"
akan memperluas urutan backslash-escaped seperti\x2F
(karakter ASCII yang nilai heksadesimalnya 2F, yaitu/
) untuk akhirnya memberi Andafoo /bar
.sumber
Perintah yang Anda tanyakan tentang penguraian
+
es dan%
urutan dari URL bukan hanya sebuahsed
perintah, ini adalah pipa yang memproses inputsed
, lalu mengirimnya ke pipaxargs
untuk diproses lebih lanjut. Pertama mari kita lihatsed
perintahnya:Anda mungkin lebih terbiasa melihatnya dengan
/
daripada@
sebagai pemisah, yang bisa dengan mudah dilakukan di sini tanpa kerumitan karena tidak/
muncul dalam pola pencarian maupun teks pengganti. Perintah ini setara:Seperti
/
,@
adalah karakter tanda baca yang sangat baik untuksed
.Di setiap baris input:
s@+@ @g
(s/+/ /g
) Mengganti (s
) kemunculan+
dengan spasi. Ini memengaruhi semua+
es pada baris (g
), bukan hanya yang pertama.;
mengakhiri aksi ("perintah") dan memungkinkan Anda menentukan yang lain di "skrip" yang sama.s@%@\\x@g
(s/%/\\x/g
) pengganti (s
) kejadian%
dengan\x
. Seperti sebelumnya, ini bertindak pada semua, bukan hanya yang pertama dari setiap baris (g
).Di
\\x
dalam\\
hanya mewakili satu\
karena\
memiliki arti khusus untuksed
. Arti istimewanya sebenarnya adalah sebagai karakter yang Anda gunakan untuk menghilangkan makna khusus dari karakter lain yang muncul setelahnya yang seharusnya memiliki makna khusus. Jadi harus diloloskan sebagai\\
.Sekarang mari kita lihat
xargs
perintah, yang tujuannya dijalankanprintf
.xargs
membangun baris perintah. Jika Anda menjalankan , di mana satu kata atau lebih, berjalan dengan argumen baris perintah tambahan yang dibaca dari inputnya. Dalam hal ini, input ke adalah output dari , karena pipa ( ). Biasanya menginterpretasikan spasi putih apa pun dalam inputnya untuk berarti bahwa teks sebelum dan sesudahnya merupakan argumen yang terpisah, tetapi opsi membuatnya memecah argumen pada kemunculan karakter nol sebagai gantinya.xargs command...
command...
xargs
command...
xargs
sed
|
xargs
-0
Dalam penggunaan perintah yang dimaksudkan, karakter nol tidak akan muncul dan
xargs
akan berjalanprintf %b
hanya dengan satu argumen baris perintah tambahan, output darised
perintah. Dengan demikian, meskipun tidak setara secara umum, dalam hal ini seluruh pipa mungkin telah ditulis seperti ini menggunakan substitusi perintah alih-alihxargs
:Adapun apa
printf
yang dimaksudkan untuk dilakukan di sini, seperti Muru mengatakan yang%b
mengkonsumsi Format specifier dan mencetak argumen (seperti%s
) tapi menyebabkan lolos backslash - dari jenis yangsed
perintah di sisi kiri pipa ditulis untuk menghasilkan - untuk diterjemahkan ke dalam karakter yang mereka wakili .Misalkan saya menjalankan perintah itu dan lulus
http://foldoc.org/debugging%20by%20printf
sebagai input. Saya mendapatkanhttp://foldoc.org/debugging by printf
sebagai output, karena%20
urutan diterjemahkan ke dalam spasi.sumber
Itulah keindahannya
sed
, itu berlaku paradigma untuk dirinya sendiri ... Setelah perintah (sepertis
atautr
atau tidak), karakter berikutnya dianggap pemisah.Anda harus memilih dengan bijak untuk menghindari gangguan pada shell dan perintah itu sendiri, dan menjaga hal itu mudah dibaca, tetapi sangat valid untuk menulis sesuatu yang mengerikan seperti:
... dan dapatkan
brrivbl
hasilnya, itulah yang Anda harapkan. Anda bisa bersenang-senang membuatnya benar-benar samar, seperti di:Penggunaan umum adalah menggunakan slash sebagai pembatas, tetapi ketika ekspresi Anda mengandung pembatas, itu membuatnya lebih mudah untuk mengambil maksudnya. Pembatas Anda bisa berupa apa saja dalam rentang ASCII8 (pembatas multibyte seperti
£
memancing kesalahan).Ingat saja tujuannya adalah untuk membuat segalanya lebih mudah, tidak lebih samar.
sumber
sed "snack is an apple or something" <<< "I sed your snack is an apple or something"
sed
perintah sebagai permainan asah otak juga, seberapa serakah itu?