Split: bagaimana membagi menjadi persentase yang berbeda?

14

Bagaimana saya bisa membagi file teks menjadi 70% dan 30% menggunakan perintah split?

aneuryzm
sumber
Apakah Anda ingin menggunakan perintah split? Jika tidak, Anda dapat dengan mudah melakukan ini dengan manipulasi teks lurus, tentu menggunakan perl atau python. Selama file tersebut tidak terlalu salah, bacalah ke memori sebagai string, lalu pisahkan string tersebut. Jika file terlalu besar, maka dibutuhkan lebih banyak pekerjaan.
Faheem Mitha
@Faheem Mitha File ini berukuran 64MB. Saya suka ide menggunakan split karena lebih cepat daripada menulis kode. Saya heran sekarang jika saya menentukan jumlah baris yang sesuai 70% dari file, saya mendapatkan file besar dan file kecil. Bukankah seharusnya itu bekerja?
aneuryzm
Dan ya .. itu berhasil .. Haruskah saya menghapus pertanyaan?
aneuryzm
Terserah Anda, tetapi tidak perlu.
Faheem Mitha
Silakan bagikan jawaban Anda. ( meta.stackexchange.com/questions/12513/… )
dogbane

Jawaban:

13

Perintah di bawah ini akan bekerja untuk persentase di atas 50% (jika Anda ingin membagi hanya menjadi dua file), pendekatan cepat dan kotor.

1) membagi 70% berdasarkan garis

split -l $[ $(wc -l filename|cut -d" " -f1) * 70 / 100 ] filename 

2) membagi 70% berdasarkan byte

split -b $[ $(wc -c filename|cut -d" " -f1) * 70 / 100 ] filename
forcefsck
sumber
1
Pada MacOSX, wc terkadang mengembalikan jumlah baris dengan spasi di depannya, sesuatu yang merusak skrip ini. Perpipaan pertama ke xargs akan menghapus ruang-ruang itu dan membuat semuanya berfungsi lagi: split -l $[ $(wc -l filename | xargs | cut -d" " -f1) * 70 / 100 ] filename
Emil Stenström
4

Anda dapat menggunakan csplituntuk membagi menjadi dua bagian (menggunakan persentase berapa pun) mis. Bagian pertama - 20% pertama dari baris, bagian kedua - 80% sisanya dari baris:

csplit infile $(( $(wc -l < infile) * 2 / 10 + 1))

$(wc -l < infile): Jumlah baris
2 / 10: persentase
+1: menambahkan satu baris karena csplitperpecahanup to but not including line N

Anda hanya dapat membagi berdasarkan garis.
Pada dasarnya, selama Anda memiliki nomor baris melalui $(( $(wc -l < file) * 2 / 10))Anda dapat menggunakan alat berorientasi garis apa pun:

sed 1,$(( $(wc -l < infile) * 2 / 10))'{
w 20-infile
d
}' infile > 80-infile

atau, lebih dingin:

{ head -n$(( $(wc -l < infile) * 2 / 10)) > 20-infile; cat > 80-infile; } <infile

meskipun beberapa heads bodoh dan tidak akan mematuhi standar sehingga ini tidak akan berfungsi pada semua pengaturan ...

don_crissti
sumber
2
{   BS=$(($(wc -c <file) * $P / 100))
    dd count=1 bs="$BS" >file1; cat
} <file >file2 2>/dev/null

... harus bekerja untuk kasing sederhana ini karena Anda hanya membelah sekali - dan mungkin splitsedikit berlebihan. Selama file dapat dicari, ddhanya akan melakukan satu read()aktif <stdin, dan catdibiarkan untuk memulai read()pada titik apa pun ddmeninggalkannya.

Jika file tersebut besar maka count=1 bs=$big_ol_numbisa menjadi sedikit berat, dan itu dapat diblokir dengan beberapa shell matematika ekstra - namun sederhana.

Input yang tidak dapat dicari - seperti dari pipa - mungkin memiringkan ddhasil, meskipun ini dapat ditangani juga dengan GNUdd ' s iflag=fullblock.

mikeserv
sumber
0

Kode berikut ini menggunakan headdan tailbekerja dengan rasio apa pun (40 hingga 60 dalam hal ini):

export FILE_NAME=train.vw
head -n $[ $(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100 ] ${FILE_NAME} > train_40.vw
tail -n +$[ ($(wc -l ${FILE_NAME}|cut -d" " -f1) * 40 / 100) + 1 ] ${FILE_NAME} > train_60.vw
Alexandr Nikitin
sumber