Membagi file dengan baris dan memiliki kontrol atas ekstensi file yang dihasilkan

28

Ada perintah standar untuk pemisahan file - split.

Misalnya, jika saya ingin membagi file kata dalam beberapa potongan 10.000 baris, saya dapat menggunakan:

split -dl 10000 words wrd

dan itu akan menghasilkan beberapa file dari form wrd.01, wrd.02 dan seterusnya.

Tapi saya ingin memiliki ekstensi spesifik untuk file-file itu - misalnya, saya ingin mendapatkan file wtd.01.txt, wrd.02.txt.

Apakah ada cara untuk melakukannya?

Rogach
sumber

Jawaban:

12

Tidak dengan split, tetapi Anda dapat dengan mudah mengganti nama mereka setelahnya, atau Anda dapat melakukannya di awk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile
Kevin
sumber
Terlihat bagus - tetapi tidak berhasil. Dalam formulir Anda, komplain tentang "ekspresi untuk pengalihan` >> 'memiliki nilai string nol ", dan jika" file "diubah" menjadi "nama file", menampilkan file-file dari form wrd. {File number}. {Line number} .txt (cukup banyak dari mereka :)
Rogach
@Rogach Maaf, saya belum mengujinya, jadi saya lupa awk tidak melakukan pembagian integer. Saya sudah menguji yang ini.
Kevin
49

Ini tidak tersedia saat itu tetapi dengan versi yang lebih baru ( ≥ 8.16) gnu splitseseorang dapat menggunakan --additional-suffixsaklar untuk memiliki kontrol atas ekstensi yang dihasilkan. Dari man split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

jadi ketika menggunakan opsi itu:

split -dl 10000 --additional-suffix=.txt words wrd

potongan yang dihasilkan akan secara otomatis berakhir pada .txt:

wrd00.txt
wrd01.txt
.........
don_crissti
sumber
3
Tidak bekerja di mac
ericgu
2
Saya suka sarkasme Anda. Saya adalah unix n00b dari dunia Apple. Saya menggunakan OS X Yosemite dan saya tidak ingin orang lain crash dan terbakar seperti saya. Saya menguji dan mengulas di dokumen dan kami tidak memiliki parameter ini. Saya mungkin telah melewatkan sesuatu. developer.apple.com/library/mac/documentation/Darwin/Reference/…
ericgu
5
@swiftshokunin - jawaban saya berkaitan dengan gnu split, bagian dari gnu coreutils. Ini juga tersedia di OSX jika Anda menginstalcoreutils melalui homebrewtetapi perhatikan bahwa secara default, pada OSX, gnuutilitas memiliki gprepended untuk nama mereka (misalnya gstatbukan stat) sehingga Anda memanggilnya sebagai gsplit(atau mengubah PATH sesuai panduan di sini jika Anda ingin untuk menggunakannya sebagai splitlebih dari OSX split). HTH.
don_crissti
1
Jawaban bagus. pada OS X, gunakan gsplituntuk mendapatkan sufiks numerik (-d) agar berfungsi.
Brent Faust
1
wow, saya tidak tahu bahwa ada gsplit - mungkin dari coreutils yang disebutkan di atas dan memang memiliki --additional-suffix. Terima kasih kepada semua orang yang mengomentari solusi ini :)
Łukasz Rysiak
13

Tugas-tugas seperti itu paling baik dikelola dengan shell. Gunakan split dan kemudian tulis loop sederhana untuk mengubah nama file. Misalnya

for file in wrd.*
do
    mv "$file" "$file.txt"
done

akan mengganti nama file wrd.01, wrd.02, dll Anda sehingga semuanya memiliki ekstensi .txt.

Kyle Jones
sumber
Itu cukup jelas, tetapi itu akan merusak keringkasan naskah bash.
Rogach
1
Filosofi Unix adalah untuk memberi Anda satu set alat sederhana yang kemudian Anda gabungkan untuk melakukan suatu pekerjaan. "Keringkasan skrip bash" bukan persyaratan yang dinyatakan dalam pertanyaan Anda.
Kyle Jones
7
PS: split+mvkombo lebih dari 6 kali lebih cepat dari awk(kira-kira 3s vs 18s ) untuk file input 10 juta baris (75 MB) ... teks di setiap baris adalah nomor baris sendiri ... Terima kasih telah menyatakan kembali "jelas" :)
Peter.O
3
PPS: Saya baru saja memeriksa ini sedikit lebih jauh. Perbedaan kecepatan terkait dengan jumlah file yang dibuat vs jumlah pemformatan dan perhitungan aritmatika yang dilakukan oleh awk untuk setiap baris terlepas dari jumlah file output ... Menggunakan file input yang sama seperti contoh di atas: Ketika ada 100 kali lebih sedikit file, split + mvadalah 75 kali lebih cepat dari awk: Bila ada 100 kali lebih file, split + mvadalah 1,5 kali lebih cepat dari awk. Jadi, bagi saya, split + mvmetode ini menang, mudah. Ini sebagai consice (bisa dibilang lebih), dan lebih cepat dari awk.
Peter.O
1
jika Anda khawatir panjangnya 5 baris, coba ini: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Tony