Saya memiliki file yang dihasilkan oleh program yang tidak menaruh baris baru di akhir catatan. Saya ingin meletakkan baris baru di antara catatan, dan saya bisa melakukannya dengan skrip sed sederhana:
sed -e 's/}{/}\n{/g'
Masalahnya adalah bahwa file input berukuran beberapa gigabytes, dan oleh karena itu jalur input ke sed panjangnya beberapa GB. sed mencoba untuk menahan garis dalam memori, yang tidak berfungsi dalam kasus ini. Saya mencoba --unbuffered
opsi itu, tetapi sepertinya membuatnya lebih lambat dan tidak membiarkannya selesai dengan benar.
tr
untuk menerjemahkan}
ke dalam\n
dan kemudian menggunakansed
untuk menambahkan}
di akhir setiap baris? Seperti ini:tr '}' '\n' < your_file.txt| sed 's/$/}/'
printf "\n" >> file
}{
diulang sampai beberapa gigabytes akan cukup.dd if=file cbs=80 conv=unblock
akan melakukannya - tetapi jarang sesederhana itu.Jawaban:
Anda dapat menggunakan alat lain yang memungkinkan Anda mengatur pemisah rekaman input. Sebagai contoh
Perl
Variabel khusus
$/
adalah pemisah rekaman input. Mengaturnya untuk}{
mendefinisikan garis sebagai berakhiran}{
. Dengan begitu Anda dapat mencapai apa yang Anda inginkan tanpa membaca semuanya ke dalam memori.mawk atau gawk
Ini ide yang sama.
RS="}{"
mengatur pemisah rekaman ke}{
dan kemudian Anda mencetak}
, baris baru,{
(kecuali untuk catatan pertama) dan catatan saat ini.sumber
Perl untuk penyelamatan:
Pengaturan
$/
untuk\1024
akan membaca file dalam potongan 1024 byte. The$closing
variabel menangani kasus ketika sepotong berakhir di}
dan yang berikutnya dimulai dengan{
.sumber
Kamu seharusnya melakukan:
Itu mungkin solusi yang paling efisien.
Yang menempatkan
{}
untuk melindungi data trailing yang mungkin. Dengan satutr
proses lagi Anda dapat menukar itu sekitar dan melakukan baris kosong di kepala{
bidang pertama . Suka...Jadi yang pertama, dengan contoh data don, tidak:
... dan yang kedua tidak ...
Tidak ada trailing newline untuk contoh kedua - meskipun ada satu untuk yang pertama.
sumber
sed
Utilitas mirip Biner disebutbbe
Saya merasa paling mudah untuk tetap dengan sintaks sed-seperti dalam kasus ini.
Saya lebih suka menggunakan
bbe
utilitas (tersedia melalui instalasi paket {uni, linu} x, eqapt-get
). Atau di sini jika Anda salah satu dari kerumunan git, meskipun saya belum secara pribadi memeriksa tautan tertentu.1. Ini mendukung
s/before/after/
idiomIni adalah "Binary Block Editor", yang mendukung operasi sed-like (antara lain). Ini termasuk
s/before/after/
idiom substitusi super umum yang Anda butuhkan. Catatan, karena tidak ada garis per se daribbe
sudut pandang, tidak ada "global g" di akhir perintah.Sebagai tes cepat (perhatikan wajib
-e
):menghasilkan:
2. Dalam kasus spesifik Anda
}{
untuk}\n{
konversiJadi jika kita memiliki file besar yang diisi dengan jutaan angka di (katakanlah) format
{1}{2}{3}
...{1000000}
tanpa pengembalian carriage, kita dapat bertukar}{
dengan}\n{
mudah, dan memiliki semua angka satu per baris.Ini akan dengan
bbe
perintah ini :Seperti yang diuji dalam loop zsh ini, yang kami ambil hanya ekor:
Yang akan menghasilkan ini:
(Tanpa kembalinya kereta belakang tentu saja.)
sumber