Liệt kê các tệp được sắp xếp theo số lượng dòng chúng chứa


32

Làm cách nào tôi có thể liệt kê số lượng dòng trong tệp /group/book/four/word, được sắp xếp theo số dòng chúng chứa?

ls -l lệnh liệt kê chúng xuống nhưng không sắp xếp chúng


1
Bạn có muốn các tệp được liệt kê theo số dòng hoặc liệt kê số lượng dòng trong các tệp hoặc cả hai? ls -lkhông đưa ra số lượng dòng. ls -lSsắp xếp tệp theo kích thước với một số lstriển khai ( kích thước là số byte trong nội dung).
Stéphane Chazelas

Câu trả lời:


34

Bạn nên sử dụng một lệnh như thế này:

find /group/book/four/word/ -type f -exec wc -l {} + | sort -rn
  • find: tìm kiếm các tập tin trên con đường bạn muốn. Nếu bạn không muốn nó đệ quy và findviệc triển khai của bạn hỗ trợ nó, bạn nên thêm -maxdepth 1ngay trước -exectùy chọn.
  • exec: cho biết lệnh để thực thi wc -ltrên mọi tệp.
  • sort -rn: sắp xếp các kết quả bằng số theo thứ tự ngược lại. Từ lớn hơn đến thấp hơn.

(giả sử tên tệp không chứa ký tự dòng mới).


Lưu ý rằng khi truyền nhiều hơn một tệp (hoặc với một số triển khai, nhiều hơn một tệp mà nó có thể đọc), wccũng sẽ in một totaldòng, vì vậy ở đây bạn cũng sẽ nhận được một hoặc nhiều dòng "tổng cộng" trừ khi chỉ có một tệp . Bạn có thể ống grep /để loại bỏ chúng.
Stéphane Chazelas

upvote vì sortlệnh
Francisco

Làm cách nào tôi có thể lọc để chỉ hiển thị tệp có dòng X tối thiểu (loại trừ dòng X = 0 cho mẫu)?
Ma trận

11

Không đệ quy

Có lẽ là phiên bản đơn giản nhất nếu bạn không cần đệ quy:

wc -l /group/book/four/word/*|sort -n

wcđếm các dòng (tùy chọn -l) trong mọi *tệp (nhưng ẩn) ( ) bên dưới /group/book/four/word/sortsắp xếp kết quả (thông qua đường ống |) bằng số (tùy chọn -n).

Đệ quy

Ai đó đã đưa ra một nhận xét cho câu trả lời này đề cập grep -rlc, trước khi để đàn áp nó. Quả thực greplà một sự thay thế tuyệt vời, đặc biệt nếu bạn cần đệ quy:

grep -rc '^' /group/book/four/word/|tr ':' ' '|sort -n -k2

sẽ tính (tùy chọn -c) đệ quy (tùy chọn -r) các dòng khớp ( grep) '^'(nghĩa là bắt đầu các dòng) trong thư mục /group/book/four/word/. Sau đó, bạn phải thay thế dấu hai chấm bằng một khoảng trắng, ví dụ: bằng cách sử dụng tr, để trợ giúp sort, mà bạn muốn sắp xếp số (tùy chọn -n) trên cột thứ hai (tùy chọn -k2).

Cập nhật: Xem bình luận của Stephane về những hạn chế có thể có và cách bạn thực sự có thể thoát khỏi tr.


3
grep -c .đếm các dòng chứa ít nhất một ký tự hợp lệ. Sử dụng grep -c '^'để đếm tất cả các dòng (cũng sẽ đếm các ký tự theo sau dòng mới cuối cùng với một số greptriển khai). Lưu ý rằng không phải tất cả các greptriển khai đều hỗ trợ a -rvà hành vi khác nhau giữa những người thực hiện. Bạn không cần dịch :s (dấu hai chấm, không phải dấu chấm phẩy) sang dấu cách sort. Chỉ cần sử dụng -t:. Lưu ý rằng giả sử tên tệp không chứa :hoặc ký tự trống hoặc dòng mới.
Stéphane Chazelas

1
Cảm ơn đã đăng giải pháp không đệ quy của bạn; Tôi không biết wcđã đưa ra tổng số tiện dụng như vậy nếu bạn vượt qua nhiều con đường. Kết hợp chức năng đó với thẻ hoang dã và đường ống để sortthực sự sạch sẽ.
Qcom

7

Với zsh:

lines() REPLY=$(wc -l < $REPLY)
printf '%s\n' /group/book/four/word/*(.no+lines)

Chúng tôi xác định một chức năng sắp xếp mới linestrả lời với số lượng dòng trong tệp. Và chúng tôi sử dụng o+linesvòng loại toàn cầu cùng với n(đối với sắp xếp số), xác định cách kết quả của toàn cầu được sắp xếp. ( .cũng được thêm vào để chỉ kiểm tra các tập tin thông thường).

Điều đó làm cho không có giả định nào về tên ký tự mà tên tệp có thể chứa ngoài các tệp bị ẩn (những tệp bắt đầu bằng .) được bỏ qua. Thêm Dvòng loại toàn cầu nếu bạn muốn họ là tốt.


2
OP chỉ được gắn thẻ bash...
l0b0

7
@ l0b0 điều đó không có nghĩa là người tiếp theo cần điều này cũng sẽ chạy bash.
terdon

4

Bạn không chỉ định liệu bạn cũng muốn các tệp trong bất kỳ thư mục con nào /group/book/four/word. Các findgiải pháp trong câu trả lời jherran sẽ rơi vào thư mục con. Nếu điều đó là không muốn, thay vào đó hãy sử dụng shell:

for file in ./*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Nếu tên tệp của bạn có thể chứa dòng mới, bạn có thể sử dụng một cái gì đó như:

for file in ./*; do 
    [ -f "$file" ] && 
        printf "%lu %s\0" "$(wc -l < "$file")" "$file"
done | sort -zn | tr '\0' '\n'

Cuối cùng, nếu bạn làm muốn đi vào trong thư mục con, bạn có thể sử dụng trong bash4 hoặc cao hơn:

shopt -s globstar
for file in ./**/*; do [ -f "$file" ] && wc -l "$file"; done | sort -n

Lưu ý rằng các phiên bản bashtrước 4.3 đã theo các liên kết tượng trưng khi đệ quy giảm dần cây thư mục (như zsh's hoặc tcsh' ***/*).

Ngoài ra, tất cả các giải pháp ở trên sẽ bỏ qua các tệp ẩn (những tệp có tên bắt đầu bằng a ., sử dụng shopt -s dotglobđể bao gồm chúng) và cũng sẽ bao gồm số dòng liên kết tượng trưng ( findcách tiếp cận sẽ không).


Lưu ý rằng sự khác biệt khác từ giải pháp của jherran là bạn cũng sẽ xem xét liên kết tượng trưng đến các tệp thông thường ( -xtype ftrong GNU find hoặc *(-.)zsh) và sẽ bỏ qua các tệp ẩn.
Stéphane Chazelas

@ StéphaneChazelas cảm ơn, làm rõ. Tại sao %lutrong printf? Như tôi nhớ, điều đó có nghĩa là số thập phân không dấu dài, nó có thực sự cần thiết không? Tại sao không coi số là một chuỗi? Liệu nó có làm cho một sự khác biệt?
terdon

2
Nếu đầu ra wc trống (ví dụ vì tệp không thể đọc được), thì điều đó sẽ mở rộng thành 0thay vì chuỗi trống, tốt hơn một chút. Một số triển khai sắp xếp làm việc với số nguyên không dấu một số có ký hiệu. %luNghe có vẻ như đặt cược an toàn nhất, nhưng có lẽ không quan trọng bằng việc bạn có 2^31đường dây, điều đó sẽ mất nhiều thời gian.
Stéphane Chazelas

1

Nếu bạn muốn cài đặt fdmột công cụ tìm tập tin thực sự nhanh được viết bằng Rust (bạn nên cài đặt nó, dù sao thì thật tuyệt)

fd --type=file . | xargs wc -l | sort -n

Về cơ bản fdliệt kê các tệp, xargs sẽ chuyển danh sách các tệp tới wc(viết tắt của đếm từ nhưng chuyển -l sẽ làm cho nó đếm các dòng), cuối cùng nó được sắp xếp từ số lượng dòng ít nhất đến lớn nhất bằng cách sử dụng sort -n.

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.