Bagaimana Anda mendaftar jumlah baris setiap file dalam direktori dalam format yang dapat dibaca manusia.

41

Saya memiliki daftar direktori dan subdirektori yang berisi file csv besar. Ada sekitar 500 juta baris dalam file-file ini, masing-masing adalah catatan. Saya ingin tahu

  1. Berapa banyak baris dalam setiap file.
  2. Berapa banyak baris dalam direktori.
  3. Berapa banyak garis secara total

Yang paling penting, saya membutuhkan ini dalam 'format yang dapat dibaca manusia' misalnya. 12.345.678 daripada 12345678

Akan menyenangkan untuk belajar bagaimana melakukan ini dalam 3 cara. Alat bash vanila polos, awk dll., Dan perl (atau python).

Hexatonis
sumber

Jawaban:

57

Berapa banyak baris dalam setiap file.

Gunakan wc, awalnya untuk jumlah kata, saya percaya, tetapi dapat melakukan garis, kata, karakter, byte, dan panjang garis terpanjang. The -lpilihan mengatakan itu untuk menghitung garis.

wc -l <filename>

Ini akan menampilkan jumlah baris dalam:

$ wc -l /dir/file.txt
32724 /dir/file.txt

Anda juga dapat mengirim data ke pipa wc:

$ cat /dir/file.txt | wc -l
32724
$ curl google.com --silent | wc -l
63

Berapa banyak baris dalam direktori.

Mencoba:

find . -name '*.pl' | xargs wc -l

satu kalimat lagi:

( find ./ -name '*.pl' -print0 | xargs -0 cat ) | wc -l

BTW, wcperintah menghitung kode baris baru, bukan baris. Ketika baris terakhir dalam file tidak berakhir dengan kode baris baru, ini tidak akan dihitung.

Anda dapat menggunakan grep -c ^, contoh lengkap:

#this example prints line count for all found files
total=0
find /path -type f -name "*.php" | while read FILE; do
     #you see use grep instead wc ! for properly counting
     count=$(grep -c ^ < "$FILE")
     echo "$FILE has $count lines"
     let total=total+count #in bash, you can convert this for another shell
done
echo TOTAL LINES COUNTED:  $total

Berapa banyak garis secara total

Tidak yakin saya mengerti permintaan Anda dengan benar. mis. ini akan menampilkan hasil dalam format berikut, menunjukkan jumlah baris untuk setiap file:

# wc -l `find /path/to/directory/ -type f`
 103 /dir/a.php
 378 /dir/b/c.xml
 132 /dir/d/e.xml
 613 total

Atau, untuk hanya menghasilkan total jumlah karakter baris baru tanpa file dengan jumlah file ke perintah berikut ini dapat terbukti berguna:

# find /path/to/directory/ -type f -exec wc -l {} \; | awk '{total += $1} END{print total}'
 613

Yang paling penting, saya membutuhkan ini dalam 'format yang dapat dibaca manusia' misalnya. 12.345.678 daripada 12345678

Bash memiliki fungsi printf bawaan :

printf "%0.2f\n" $T

Seperti biasa, ada banyak metode berbeda yang dapat digunakan untuk mencapai hasil yang sama yang disebutkan di sini.

malyy
sumber
Ngomong-ngomong, bagaimana saya menggunakan printf dalam contoh Anda? Saya mencoba untuk pipa dari wc -l, tetapi tidak berhasil.
Hexatonic
coba> temukan. -nama '* .pl' | xargs wc -l | awk '{printf ("% 0.2f", $ 1)} {print $ 2}' ubah output dari 'printf' untuk kebutuhan Anda
malyy
Ini tidak menambahkan koma ke nomor untuk membuatnya lebih mudah dibaca manusia. Itu hanya menambahkan nol sampai akhir.
Hexatonic
gema 100000000000000 | xargs printf "% 'd \ n" 1.000.000.000.000
Hexatonic
1
@Hexatonic printftidak membaca argumennya stdin, tetapi dari baris perintah (bandingkan perpipaan dengan echovs perpipaan cat; catdibaca dari stdin, echotidak). Sebagai gantinya, gunakan printf "$(find ... | xargs ...)"untuk memasok output sebagai argumen printf.
BallpointBen
13

Dalam banyak kasus, menggabungkan wcperintah dan wildcard *mungkin cukup.
Jika semua file Anda berada dalam satu direktori, Anda dapat menghubungi:

wc -l src/*

Anda juga dapat membuat daftar beberapa file dan direktori:

wc -l file.txt readme src/* include/*

Perintah ini akan menampilkan daftar file dan jumlah barisnya.
Baris terakhir adalah jumlah baris dari semua file.


Untuk menghitung semua file dalam direktori secara rekursif:

Pertama, aktifkan globstar dengan menambahkan shopt -s globstar.bash_profile Anda. Dukungan untuk globstar membutuhkan Bash ≥ 4.x yang dapat diinstal brew install bashjika diperlukan. Anda dapat memeriksa versi Anda dengan bash --version.

Lalu lari:

wc -l **/*

Perhatikan bahwa output ini akan salah jika globstar tidak diaktifkan.

Thomio
sumber
Dan untuk menghitung file dalam direktori currrent secara rekursif:wc -l **/*
Taylor Edmiston
@TaylorEdmiston Bagi saya (di Mac) yang hanya menghitung file persis satu direktori ke bawah. Itu melompati file dalam direktori saat ini, dan untuk setiap contoh yang akan lebih dari satu direktori yang dalam itu memperingatkan bahwa itu adalah direktori: " wc: parent_dir/child_dir: read: Is a directory"
M. Justin
@Thomio Membutuhkan globstar harus diaktifkan. Di macOS, saya percaya ini dinonaktifkan di luar kotak. Saya baru saja mengirim hasil edit untuk jawaban Anda yang menambahkan perintah dan cara mengaktifkan globstar.
Taylor Edmiston
2

Perintah ini akan memberikan daftar kode baris di setiap direktori:

find . -name '*.*' -type f | xargs wc -l
Suresh
sumber
2

agak terlambat ke permainan, tapi saya mendapat banyak kesalahan argumen dengan di atas karena ukuran dir. Ini bekerja untuk saya:

for i in $(find . -type f); do wc -l $i; done >> /home/counts.txt

Ron Paulfan
sumber
0

catakan menggabungkan file menjadi satu dan mengeluarkan segalanya untuk stdout, Anda dapat melakukan wc -litu untuk jumlah total baris file dalam direktori:

cat /path/to/directory/* | wc -l
teman pik 涅
sumber
0

Saya hanya akan menambah jawaban @malyy untuk yang berikut (menjadi besar untuk komentar):

Berapa banyak garis secara total

Banyak jawaban yang digunakan wc opsi file baris perintah dengan xargs. Masalah dengan ini adalah xargs terbatas pada ukuran ketergantungan platform yang agak kecil.

Selanjutnya ada perbedaan antara BSD (macOS) dan GNU (linux / homebrew) wc .

GNU yang ideal karena dapat membaca daftar file dari file, bukan argumen (--files0 ).

Jika Anda menggunakan mac dan memiliki homebrew, Anda harus melakukan hal berikut:

find . -name "*.pl" -print0 | gwc -l --files0=-

Perhatikan gwc bukan wc .

Adam Gent
sumber