Saya memiliki file yang berisi teks dalam paragraf (baris dengan teks dipisahkan oleh satu atau lebih baris kosong). Saya ingin membalik urutan paragraf (yaitu paragraf terakhir akan menjadi yang pertama, ...), lebih disukai dengan menggunakan sed.
Saya mencari perintah sed yang akan dilakukan untuk file paragraf, apa yang tac
akan dilakukan untuk file baris.
sumber
Mungkin ada cara untuk melakukan ini
sed
, tapi saya ragu itu akan sederhana. Inilah cara saya akan melakukannya di Perl:Ini berfungsi karena mendefinisikan pemisah rekaman input sebagai karakter nol (
-00
) memberitahu Perl untuk beroperasi dalam mode paragraf. Definisi Perl tentang paragraf 1 sangat cocok dengan definisi Anda.1 Lihat di bawah judul
Other values for $/
sumber
Jika paragraf Anda selalu dipisahkan oleh satu baris kosong:
Ini cukup mudah untuk melihat cara kerjanya jika Anda memecahnya menjadi potongan-potongan dan menjalankan
sed '/^$/s/^/\x02/' infile
kemudiansed '/^$/s/^/\x02/' infile | tr \\n$'\002' $'\003'\\n
dan seterusnya ...Jika paragraf Anda dipisahkan oleh satu atau lebih baris kosong, mis
dan Anda ingin membalik urutan paragraf tetapi mempertahankan urutan "blok kosong" Anda bisa membaca file dua kali:
1: mengubah paragraf menjadi baris tunggal (menghapus blok kosong di antara) dan membalikkannya dan
2: mengubah blok kosong menjadi satu baris, "mengindeks" jumlah baris kosong di setiap blok (dan menghapus garis tidak kosong)
kemudian
paste
hasil dan proses output untuk mengembalikan baris baru:yang keluaran:
Jika Anda tidak keberatan dengan garis trailing tambahan di output, Anda bisa menghapus yang terakhir
sed
:Ini mengasumsikan bahwa baris pertama dan terakhir tidak kosong (dan tidak ada
\x02
,\x03
atau\x04
dalam input).sumber
Anda BISA melakukannya dengan satu instance dari
sed
; tidak perlu pipa. Karenased
hanya membuat satu melewati dokumen dan karena bagian dari file yang diperlukan sebagai awal output adalah di akhir file, itu akan memerlukan memegang seluruh file dalam memori di dalamsed
(di ruang penahanan) —jadi mungkin tidak skala dengan baik. Tapi itu menjawab pertanyaan dengan tepat:Jika tidak ada trailing newline, ini masih berfungsi dengan baik. Jika ada satu baris baru yang tertinggal, itu ditekan dalam output (yaitu tidak akan ada baris baru dalam output). Jika ada (misalnya) 5 baris baru di input, akan ada 4 baris baru di output.
Kesenjangan antar paragraf dipertahankan.
Spasi putih pada baris yang kosong TIDAK diperlakukan sebagai paragraf break, tapi itu fitur, bukan bug. :)
Anda juga dapat melakukan ini sebagai one-liner yang jauh lebih mudah dibaca:
Meskipun ini hanya berfungsi dengan GNU
sed
. (Catat penggunaan backreferences yang sulit untuk dilakukans/$/\n/
. Tanpa ini, itu tidak akan menjadi satu-liner literal karena akan mengandung garis miring terbalik-baru.)sumber
G;h
. Anda mungkin menyebutkan sesuatu tentang batasan input atau sejenisnya.sed
berguna, tetapi versi skrip pasti menjaga celah di antara paragraf. Saya baru saja mengujinya atas masukan Anda. Apakah Anda menguji versi skrip?Ini harus menjaga jarak paragraf Anda (sementara lebih mudah dibaca daripada
sed
:)) Meskipun, alat untuk devnull untuk jawaban yang luar biasa.sumber