Saya memiliki file .msg yang agak besar yang diformat dalam format UIEE.
$ wc -l big_db.msg
8726593 big_db.msg
Pada dasarnya, file terdiri dari entri dengan panjang berbeda yang terlihat seperti ini:
UR|1
AA|Condon, Richard
TI|Prizzi's Family
CN|Collectable- Good/Good
MT|FICTION
PU|G.P. Putnam & Sons
DP|1986
ED|First Printing.
BD|Hard Cover
NT|0399132104
KE|MAFIA
KE|FICTION
PR|44.9
XA|4
XB|1
XC|BO
XD|S
UR|10
AA|Gariepy, Henry
TI|Portraits of Perseverance
CN|Good/No Jacket
MT|SOLD
PU|Victor Books
DP|1989
BD|Mass Market Paperback
NT|1989 tpb g 100 meditations from the Book of Job "This book...help you
NT| persevere through the struggles of your life..."
KE|Bible
KE|religion
KE|Job
KE|meditations
PR|28.4
XA|4
XB|5
XC|BO
XD|S
Ini adalah contoh dari dua entri, dipisahkan oleh baris kosong. Saya ingin membagi file besar ini menjadi file yang lebih kecil tanpa memecah entri menjadi dua file.
Setiap entri individual dipisahkan oleh baris baru (baris yang benar-benar kosong) dalam file. Saya ingin memecah 8,7 juta file baris ini menjadi 15 file. Saya mengerti bahwa alat-alat seperti split
ada tetapi saya tidak yakin bagaimana cara membagi file tetapi hanya membaginya pada baris baru sehingga satu entri tidak bisa dipecah menjadi beberapa file.
text-processing
split
pengguna2036066
sumber
sumber
csplit
juga ada.|
(sepertiUR
,AA
,TI
) relevan untuk hitungan file, bahkan sama tepatnya?Jawaban:
Inilah solusi yang bisa bekerja:
Ini bekerja dengan memungkinkan yang pertama
sed
untuk menulissed
skrip kedua . Yangsed
pertama mengumpulkan semua jalur input sampai bertemu dengan baris kosong. Itu kemudian menulis semua jalur output ke file. Yang pertamased
menulis naskah untuk yang kedua menginstruksikannya di mana untuk menulis hasilnya. Dalam kasus pengujian saya skrip itu terlihat seperti ini:Saya mengujinya seperti ini:
Ini memberi saya file 6000 baris, yang terlihat seperti ini:
... diulang 1000 kali.
Setelah menjalankan skrip di atas:
KELUARAN
sumber
Menggunakan saran dari
csplit
:Pemisahan berdasarkan nomor baris
Contoh
Katakanlah saya punya file dengan 1000 baris di dalamnya.
menghasilkan file seperti ini:
Anda dapat mengatasi batasan statis karena harus menentukan jumlah pengulangan dengan pra-kalkulasi angka berdasarkan jumlah baris dalam file tertentu Anda sebelumnya.
Pemisahan berdasarkan garis kosong
Jika di sisi lain Anda hanya ingin membagi file pada baris kosong yang terkandung dalam file Anda dapat menggunakan versi
split
:Contoh
Katakanlah saya telah menambahkan 4 baris kosong ke
file.txt
atas, dan buat filefile2.txt
. Anda dapat melihat bahwa mereka telah ditambahkan secara manual seperti:Di atas menunjukkan bahwa saya telah menambahkan mereka di antara angka-angka yang sesuai dalam file sampel saya. Sekarang ketika saya menjalankan
csplit
perintah:Anda dapat melihat bahwa saya sekarang memiliki 4 file yang telah dibagi berdasarkan baris kosong:
Referensi
sumber
Jika Anda tidak peduli dengan pesanan catatan, Anda bisa melakukannya:
Jika tidak, Anda harus terlebih dahulu mendapatkan jumlah catatan terlebih dahulu, untuk mengetahui berapa banyak yang dimasukkan ke dalam setiap file output:
sumber
file.in
danfile.out
?Jika Anda ingin memecah hanya pada akhir baris, Anda harus dapat melakukannya dengan
-l
opsi untuksplit
.Jika Anda ingin membagi pada baris kosong (
\n\n
), berikut adalah cara saya melakukannya di ksh. Saya belum mengujinya, dan mungkin itu tidak ideal, tetapi sesuatu di sepanjang baris ini akan berfungsi:sumber
\n\n
, saya pikir.\n\n
, tetapi bukan untuk membagi di tengah garis. Dia menyebut baris baru sebagai garis kosong.Mencoba
awk
sumber
Jika Anda tidak peduli dengan urutan catatan tetapi Anda khususnya tentang mendapatkan sejumlah file output, jawaban Stephane adalah cara saya akan pergi. Tapi saya merasa Anda mungkin lebih peduli menentukan ukuran yang setiap file output tidak boleh melebihi. Itu sebenarnya membuatnya lebih mudah karena Anda dapat membaca file input Anda dan mengumpulkan catatan sampai Anda mencapai ukuran itu, dan kemudian mulai file output baru. Jika itu cocok untuk Anda, sebagian besar bahasa pemrograman dapat menangani tugas Anda dengan skrip pendek. Berikut ini adalah implementasi awk:
Masukkan ini ke dalam file, katakan
program.awk
, dan jalankan denganawk -v maxlen=10000 -f program.awk big_db.msg
nilai nilainyamaxlen
adalah yang paling Anda inginkan dalam satu file. Ini akan menggunakan 500k sebagai default.Jika Anda ingin mendapatkan sejumlah file, mungkin cara termudah adalah dengan membagi ukuran file input Anda dengan jumlah file yang Anda inginkan, dan kemudian menambahkan sedikit ke nomor yang ingin Anda dapatkan
maxlen
. Misalnya, untuk mendapatkan 15 file dari 8726593 byte Anda, bagilah dengan 15 untuk mendapatkan 581773, dan tambahkan beberapa, jadi mungkin berikanmaxlen=590000
ataumaxlen=600000
. Jika Anda ingin melakukan ini berulang-ulang, Anda mungkin dapat mengkonfigurasi program untuk melakukannya.sumber