Làm thế nào để bạn liệt kê số lượng dòng của mỗi tệp trong một thư mục ở định dạng có thể đọc được.


40

Tôi có một danh sách các thư mục và thư mục con chứa các tệp csv lớn. Có khoảng 500 triệu dòng trong các tệp này, mỗi tệp là một bản ghi. Tôi muốn biết

  1. Có bao nhiêu dòng trong mỗi tệp.
  2. Có bao nhiêu dòng trong thư mục.
  3. Tổng cộng có bao nhiêu dòng

Quan trọng nhất, tôi cần điều này ở 'định dạng có thể đọc được của con người', vd. 12.345.678 chứ không phải 12345678

Sẽ thật tuyệt khi học cách làm điều này theo 3 cách. Công cụ bash vanilla đồng bằng, awk, vv và perl (hoặc python).

Câu trả lời:


56

Có bao nhiêu dòng trong mỗi tệp.

Sử dụng wc, ban đầu để đếm từ, tôi tin, nhưng nó có thể thực hiện các dòng, từ, ký tự, byte và độ dài dòng dài nhất. Các -ltùy chọn cho nó để đếm dòng.

wc -l <filename>

Điều này sẽ xuất số lượng dòng trong:

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

Bạn cũng có thể dẫn dữ liệu vào wc:

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

Có bao nhiêu dòng trong thư mục.

Thử:

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

một lớp lót khác:

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

BTW, wclệnh đếm mã dòng mới, không phải dòng. Khi dòng cuối cùng trong tệp không kết thúc bằng mã dòng mới, điều này sẽ không được tính.

Bạn có thể sử dụng grep -c ^, ví dụ đầy đủ:

#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

Tổng cộng có bao nhiêu dòng

Không chắc chắn rằng tôi hiểu bạn yêu cầu chính xác. ví dụ: điều này sẽ xuất kết quả theo định dạng sau, hiển thị số lượng dòng cho mỗi tệp:

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

Ngoài ra, để chỉ xuất tổng số ký tự dòng mới mà không có tệp theo số lượng tệp theo lệnh sau có thể chứng minh hữu ích:

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

Quan trọng nhất, tôi cần điều này ở 'định dạng có thể đọc được của con người', vd. 12.345.678 chứ không phải 12345678

Bash có chức năng printf được xây dựng trong:

printf "%0.2f\n" $T

Như mọi khi, có nhiều phương pháp khác nhau có thể được sử dụng để đạt được kết quả tương tự được đề cập ở đây.


Nhân tiện, làm thế nào để tôi sử dụng printf trong các ví dụ của bạn? Tôi đã cố gắng chuyển sang nó từ wc -l, nhưng nó không hoạt động.
Hexatonic

thử> tìm. -name '* .pl' | xargs wc -l | awk '{printf ("% 0.2f", $ 1)} {print $ 2}' thay đổi đầu ra của 'printf' cho nhu cầu của bạn
malyy

Điều này không thêm dấu phẩy vào số để làm cho nó dễ đọc hơn. Nó chỉ thêm một số không vào cuối.
Hexatonic

tiếng vang 1000000000000 | xargs printf "% 'd \ n" 1.000.000.000.000
Hexatonic

1
@Hexatonic printfkhông đọc các đối số của nó từ stdin, mà là từ dòng lệnh (so sánh đường ống với echovs đường ống đến cat; catđọc từ stdin, echokhông). Thay vào đó, sử dụng printf "$(find ... | xargs ...)"để cung cấp đầu ra dưới dạng đối số printf.
BallpointBen

13

Trong nhiều trường hợp kết hợp wclệnh và ký tự đại diện *có thể là đủ.
Nếu tất cả các tệp của bạn nằm trong một thư mục, bạn có thể gọi:

wc -l src/*

Bạn cũng có thể liệt kê một số tệp và thư mục:

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

Lệnh này sẽ hiển thị danh sách các tệp và số dòng của chúng.
Dòng cuối cùng sẽ là tổng của các dòng từ tất cả các tệp.


Để đếm tất cả các tệp trong một thư mục đệ quy:

Đầu tiên, kích hoạt globalstar bằng cách thêm shopt -s globstarvào .bash_profile của bạn. Hỗ trợ cho globalstar yêu cầu Bash 4.x có thể được cài đặt brew install bashnếu cần. Bạn có thể kiểm tra phiên bản của bạn với bash --version.

Sau đó chạy:

wc -l **/*

Lưu ý rằng đầu ra này sẽ không chính xác nếu continstar không được bật.


Và để đếm các tập tin trong thư mục hiện tại theo cách đệ quy:wc -l **/*
Taylor Edmiston

@TaylorEdmiston Đối với tôi (trên Mac) chỉ đếm các tệp chính xác một thư mục. Nó bỏ qua các tệp trong thư mục hiện tại và trong mọi trường hợp sẽ có nhiều hơn một thư mục sâu, nó cảnh báo rằng đó là một thư mục: " wc: parent_dir/child_dir: read: Is a directory"
M. Justin

@Thomio Nó yêu cầu globalstar phải được kích hoạt. Trên macOS, tôi tin rằng nó đã bị vô hiệu hóa. Tôi vừa gửi một bản chỉnh sửa cho câu trả lời của bạn có thêm lệnh và cách bật globalstar.
Taylor Edmiston

2

Lệnh này sẽ đưa ra danh sách mã dòng trong mỗi thư mục:

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

2

hơi muộn với trò chơi, nhưng tôi đã gặp một loạt lỗi đối số với phần trên do kích thước của thư mục. Điều này làm việc cho tôi:

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


0

catsẽ kết hợp các tệp thành một và xuất ra mọi thứ thành thiết bị xuất chuẩn, bạn có thể thực hiện một thao tác wc -lđó với tổng số dòng tệp trong một thư mục:

cat /path/to/directory/* | wc -l

0

Tôi sẽ chỉ tăng câu trả lời @malyy cho câu hỏi sau (to to cho một bình luận):

Tổng cộng có bao nhiêu dòng

Nhiều câu trả lời đang sử dụng wctùy chọn tệp dòng lệnh với xargs. Vấn đề với điều này là xargs bị giới hạn ở kích thước phụ thuộc nền tảng khá nhỏ.

Hơn nữa, có một sự khác biệt giữa BSD (macOS) và GNU (linux / homebrew) wc.

GNU one là lý tưởng vì nó có thể đọc danh sách tệp từ một tệp thay vì đối số ( --files0).

Nếu bạn đang dùng mac và có homebrew, bạn nên làm như sau:

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

Lưu ý gwc thay vì wc .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.