Saya bingung dengan dua konsep di sed: ruang tahan dan ruang pola. Bisakah seseorang membantu menjelaskannya?
Berikut cuplikan manualnya:
h H Copy/append pattern space to hold space. g G Copy/append hold space to pattern space. n N Read/append the next line of input into the pattern space.
Enam perintah ini sangat membingungkan saya.
echo $'1\n2\n3\n4' | sed -n '1~2h;2~2{p;x;p}'
info sed
. Ini jauh lebih rinci daripada halaman manual telanjang.Jawaban:
Ketika sed membaca file baris demi baris, garis yang telah saat membaca dimasukkan ke dalam pola penyangga (ruang pola). Pola buffer seperti buffer sementara, alas awal tempat informasi saat ini disimpan. Ketika Anda memberi tahu sed untuk mencetak, itu mencetak buffer pola.
Hold buffer / hold space seperti penyimpanan jangka panjang, sehingga Anda dapat menangkap sesuatu, menyimpannya, dan menggunakannya kembali nanti ketika sed memproses baris lain. Anda tidak langsung memproses ruang penahanan, sebaliknya, Anda perlu menyalinnya atau menambahkan ke ruang pola jika Anda ingin melakukan sesuatu dengannya. Misalnya, perintah
p
cetak hanya mencetak ruang pola. Demikian pula,s
beroperasi pada pola ruang.Berikut ini contohnya:
(opsi -n menekan pencetakan garis otomatis)
Ada tiga perintah di sini:
1!G
,h
dan$p
.1!G
memiliki alamat,1
(baris pertama), tetapi!
artinya perintah akan dieksekusi di mana saja kecuali di baris pertama.$p
di sisi lain hanya akan dieksekusi di baris terakhir. Jadi yang terjadi adalah ini:h
menyalin baris pertama ke ruang tunggu .G
, tambahkan konten buffer penahan ke buffer pola, pisahkan dengan baris baru. Ruang pola sekarang berisi baris kedua, baris baru, dan baris pertama.h
perintah memasukkan konten yang digabungkan dari buffer pola ke dalam ruang tunggu, yang sekarang menahan baris dua dan satu terbalik.Akhirnya, setelah baris terakhir dibaca dan ruang penahan (berisi semua baris sebelumnya dalam urutan terbalik) telah ditambahkan ke ruang pola, ruang pola dicetak dengan
p
. Seperti yang Anda tebak, perintah di atas melakukan persis seperti yang dilakukantac
perintah - mencetak file secara terbalik.sumber
'195,210{/add/p}'
… Apakah mungkin untuk mengekstrak baris terakhir dari sekelompok baris yang terlibat dalam sebuah pola?@ Ed Morton: Saya tidak setuju dengan Anda di sini. Saya merasa
sed
sangat berguna dan sederhana (setelah Anda menguasai konsep pola dan menahan buffer) untuk menghasilkan cara yang elegan untuk melakukan multiline grepping.Sebagai contoh, mari kita ambil file teks yang memiliki nama host dan beberapa informasi tentang setiap host, dengan banyak sampah di antaranya yang tidak saya pedulikan.
Bagi saya, skrip awk untuk mendapatkan baris dengan nama host dan
info
baris yang sesuai akan memakan waktu lebih banyak daripada yang dapat saya lakukan dengan sed:keluarannya terlihat seperti:
(Perhatikan bahwa
Host: foo1
muncul dua kali di output.)Penjelasan:
-n
menonaktifkan output kecuali dicetak secara eksplisitHost:
baris ke dalam buffer penahan (h)Host:
baris, kemudian menukar kembali (x) dan mencetak (p) baris Info:.Ya, ini adalah contoh sederhana, tetapi saya menduga ini adalah masalah umum yang dengan cepat ditangani oleh sed sederhana satu baris. Untuk tugas yang jauh lebih kompleks, seperti tugas di mana Anda tidak dapat mengandalkan urutan tertentu yang dapat diprediksi, awk mungkin lebih cocok.
sumber
grep 'Host\|Info'
awk
padanan kode sed Anda juga cukup pendek:awk '/Host:/{hold=$0}; /Info/{print hold; print;}' myfile.txt
Meski @ januari jawaban dan contohnya bagus, tapi penjelasannya belum cukup buat saya. Saya harus mencari dan belajar banyak sampai saya berhasil memahami bagaimana tepatnya
sed -n '1!G;h;$p'
bekerja. Jadi saya ingin menjelaskan tentang perintah untuk orang seperti saya.Pertama-tama, mari kita lihat apa yang dilakukan oleh perintah tersebut.
Ini membalikkan input seperti yang
tac
dilakukan perintah.sed
membaca baris demi baris, jadi mari kita lihat apa yang terjadi pada ruang patten dan ruang tunggu di setiap baris. Saath
perintah menyalin konten ruang pola ke ruang tunggu, kedua spasi memiliki teks yang sama.Pada baris terakhir,
$p
cetakand\nc\nb\na$
yang diformat menjadiJika Anda ingin melihat ruang pola untuk setiap baris, Anda dapat menambahkan
l
perintah.Saya merasa sangat membantu untuk menonton tutorial video ini Memahami cara kerja sed , karena pria itu menunjukkan bagaimana setiap ruang akan digunakan selangkah demi selangkah. Jarak penahan dirujuk dalam tutorial ke-4, tetapi saya merekomendasikan untuk menonton semua video jika Anda tidak terbiasa
sed
.Juga dokumen GNU sed dan tutorial Sed Bruce Barnett adalah referensi yang sangat bagus.
sumber