GNU/Linux >> Belajar Linux >  >> Linux

Hitung baris dalam file besar

Pada server multi-core, gunakan paralel GNU untuk menghitung baris file secara paralel. Setelah setiap jumlah baris file dicetak, bc menjumlahkan semua jumlah baris.

find . -name '*.txt' | parallel 'wc -l {}' 2>/dev/null | paste -sd+ - | bc

Untuk menghemat ruang, Anda bahkan dapat menyimpan semua file terkompresi. Baris berikut membuka kompresi setiap file dan menghitung barisnya secara paralel, lalu menjumlahkan semua hitungan.

find . -name '*.xz' | parallel 'xzcat {} | wc -l' 2>/dev/null | paste -sd+ - | bc

Sesuai pengujian saya, saya dapat memverifikasi bahwa Spark-Shell (berdasarkan Scala) jauh lebih cepat daripada alat lain (GREP, SED, AWK, PERL, WC). Berikut adalah hasil pengujian yang saya jalankan pada file yang memiliki 23782409 baris

time grep -c $ my_file.txt;

nyata 0m44.96pengguna 0m41.59ssys 0m3.09s

time wc -l my_file.txt;

nyata 0m37.57pengguna 0m33.48ssys 0m3.97s

time sed -n '$=' my_file.txt;

nyata 0m38.22pengguna 0m28.05ssys 0m10.14s

time perl -ne 'END { $_=$.;if(!/^[0-9]+$/){$_=0;};print "$_" }' my_file.txt;

nyata 0m23.38pengguna 0m20.19ssys 0m3.11s

time awk 'END { print NR }' my_file.txt;

nyata 0m19.90pengguna 0m16.76ssys 0m3.12s

spark-shell
import org.joda.time._
val t_start = DateTime.now()
sc.textFile("file://my_file.txt").count()
val t_end = DateTime.now()
new Period(t_start, t_end).toStandardSeconds()

res1:org.joda.time.Seconds =PT15S


Faktor kecepatan pembatas Anda adalah kecepatan I/O perangkat penyimpanan Anda, jadi mengubah antara baris baru/program penghitungan pola tidak akan membantu, karena perbedaan kecepatan eksekusi antara program tersebut cenderung ditekan dengan cara disk/penyimpanan yang lebih lambat/ apa pun yang Anda miliki.

Tetapi jika Anda memiliki file yang sama yang disalin ke seluruh disk/perangkat, atau file tersebut didistribusikan di antara disk tersebut, Anda pasti dapat melakukan operasi secara paralel. Saya tidak tahu secara spesifik tentang Hadoop ini, tetapi dengan asumsi Anda dapat membaca file 10 GB dari 4 lokasi berbeda, Anda dapat menjalankan 4 proses penghitungan baris yang berbeda, masing-masing dalam satu bagian file, dan menjumlahkan hasilnya:

$ dd bs=4k count=655360 if=/path/to/copy/on/disk/1/file | wc -l &
$ dd bs=4k skip=655360 count=655360 if=/path/to/copy/on/disk/2/file | wc -l &
$ dd bs=4k skip=1310720 count=655360 if=/path/to/copy/on/disk/3/file | wc -l &
$ dd bs=4k skip=1966080 if=/path/to/copy/on/disk/4/file | wc -l &

Perhatikan & di setiap baris perintah, sehingga semua akan berjalan secara paralel; dd berfungsi seperti cat di sini, tetapi izinkan kami untuk menentukan berapa banyak byte yang akan dibaca (count * bs byte) dan berapa banyak yang harus dilewati di awal input (skip * bs byte). Ini bekerja dalam blok, oleh karena itu, kebutuhan untuk menentukan bs sebagai ukuran blok. Dalam contoh ini, saya telah mempartisi file 10Gb dalam 4 potongan yang sama 4Kb * 655360 =2684354560 byte =2,5GB, satu diberikan untuk setiap pekerjaan, Anda mungkin ingin menyiapkan skrip untuk melakukannya untuk Anda berdasarkan ukuran file dan jumlah pekerjaan paralel yang akan Anda jalankan. Anda juga perlu menjumlahkan hasil eksekusi, yang belum saya lakukan karena kurangnya kemampuan skrip shell.

Jika sistem file Anda cukup pintar untuk membagi file besar di antara banyak perangkat, seperti RAID atau sistem file terdistribusi atau semacamnya, dan secara otomatis memparalelkan permintaan I/O yang dapat dilumpuhkan, Anda dapat melakukan pemisahan seperti itu, menjalankan banyak pekerjaan paralel, tetapi menggunakan jalur file yang sama, dan Anda mungkin masih mendapatkan beberapa peningkatan kecepatan.

EDIT:Gagasan lain yang terpikir oleh saya adalah, jika baris di dalam file memiliki ukuran yang sama, Anda bisa mendapatkan jumlah baris yang tepat dengan membagi ukuran file dengan ukuran baris, keduanya dalam byte. Anda dapat melakukannya hampir secara instan dalam satu pekerjaan. Jika Anda memiliki ukuran rata-rata dan tidak terlalu peduli dengan jumlah garis, tetapi menginginkan perkiraan, Anda dapat melakukan operasi yang sama ini dan mendapatkan hasil yang memuaskan jauh lebih cepat daripada operasi sebenarnya.


Coba:sed -n '$=' filename

Kucing juga tidak diperlukan:wc -l filename sudah cukup dengan cara Anda saat ini.


Linux
  1. Memindahkan file di Linux tanpa mv

  2. Perintah wc Linux

  3. Diff/patch biner untuk file besar di linux?

  1. Bagaimana Menghitung Jumlah Baris Dalam File Setelah Pertandingan Grep?

  2. Hitung Baris Dalam File?

  3. Hitung baris, kata, dan karakter dari file di Linux

  1. Sistem file Linux sedang terisi, meskipun tidak ada file atau direktori besar

  2. Cara Menghitung baris dalam file di UNIX/Linux

  3. Hitung baris semua file di direktori Ubuntu