Làm thế nào để sắp xếp kích thước con người có thể đọc được


11

Về cơ bản tôi đang tìm kiếm các tập tin sau đó sắp xếp theo kích thước. Kịch bản hoạt động nếu tôi không sắp xếp kích thước theo con người có thể đọc được. Nhưng tôi muốn kích thước có thể đọc được. Làm thế nào tôi có thể sắp xếp kích thước mà con người có thể đọc được?

Ví dụ:

 ls -l | sort -k 5 -n | awk '{print $9 " " $5}'

Điều này hoạt động như mong đợi, tôi có kích thước tệp của mình theo byte tăng dần:

1.txt 1
test.txt 3
bash.sh* 573
DocGeneration.txt 1131
andres_stuff.txt 1465
Branches.xlsx 15087
foo 23735
bar 60566
2016_stuff.pdf 996850

Bây giờ, tôi muốn kích thước có thể đọc được của con người, vì vậy tôi đã thêm một tham số -h vào ls và bây giờ một số tệp không theo thứ tự:

 ls -lh | sort -k 5 -n | awk '{print $9 " " $5}'
1.txt 1
DocGeneration.txt 1.2K
andres_stuff.txt 1.5K
test.txt 3
Branches.xlsx 15K
foo 24K
bar 60K
bash.sh* 573
2016_stuff.pdf 974K


-k 5- nó hoạt động thế nào?
ctrl-alt-delor

@ ctrl-alt-delor: Tôi tin rằng kích thước nằm ở cột thứ 5 của lsđầu ra
jesse_b

2
Sử dụng duthay vì lscó thể là một ý tưởng tốt.
xenoid

... hoặc find-printfvới nó %pvà các trình %sđịnh dạng của nó (theo sau là một bản sao nhân bản của các kích cỡ).
Stephen Kitt

@Jlie_b lỗi của tôi, tôi chỉ cho rằng dữ liệu trong câu hỏi (được đánh dấu là đây là những gì tôi nhận được) là đầu vào được sắp xếp. Tôi đã sai.
ctrl-alt-delor

Câu trả lời:


28

Thử sort -h k2

-h, --human-number-sort so sánh các số có thể đọc được của con người (ví dụ: 2K 1G)

Nó là một phần của gnu sort, BSD sort và những thứ khác.


5
Không nên phân tích cú pháp đầu ra ls?

3
@Tomasz Không phải lúc nào. Nếu nó cung cấp đầu ra mà bạn cần, việc chuyển nó sang một hoạt động định dạng khác không đặc biệt nguy hiểm. Những gì bạn không nên làm là lặp qua đầu ra của ls, và thay vào đó sử dụng trực tiếp tệp toàn cầu. Globbing một mình sẽ không làm việc ở đây. Điều đó nói rằng, tôi có lẽ sẽ thích ducho điều này.
Bloodgain

1
@Bloodgain định dạng ls không được đảm bảo giống nhau trên các nhị phân của hệ thống / ls, vì vậy việc phân tích cú pháp nó có thể được coi là không thể.
D. Ben Knoble

1
Ngoài ra, tên tệp có khoảng trắng sẽ tạo ra nhiều thứ
D. Ben Knoble

1
@Bloodgain: files=(); for f in *; do [[ -L "$f" ]] && files+=("$f"); done; echo ${#files[@]}(Tôi có thể có một chuyển đổi kiểm tra symlink sai). Nếu bạn không quan tâm đến các liên kết tượng trưng files=(*); echo ${#files[@]}, nó sẽ trở thành di động nếu bạn sử dụng setvà không phải là mảng.
D. Ben Knoble

29

lscó chức năng này được tích hợp sẵn, sử dụng -Stùy chọn và sắp xếp theo thứ tự ngược lại:ls -lShr

       -r, --reverse
              reverse order while sorting

       -S     sort by file size, largest first

1
-hkhông phải là một tùy chọn tiêu chuẩnls , nhưng phải có thể sử dụng được nếu OP đã có nó. Phần còn lại là tiêu chuẩn, và đó chắc chắn là câu trả lời tôi sẽ viết.
Toby Speight

5
+1 Đừng lộn xộn xung quanh việc phân tích cú pháp đầu ra của ls.
David Richerby

Đây là câu trả lời tốt nhất, nhưng nó nên bao gồm thông tin trong bình luận của @ Toby: -Scó thể không có sẵn cho bạn ls. FWIW, -Sđược hỗ trợ ngay cả với thư viện của Emacs ls-lisp.el, được sử dụng khi HĐH không có ls. Nó hoạt động trong Emacs trên MS Windows, ví dụ.
vẽ

Đây phải là câu trả lời được chấp nhận.
phân tán

1
@Drew: Nhận xét của Toby nói rằng -hcó thể không có sẵn trên toàn cầu, nhưng OP vẫn đang sử dụng nó. -Sthực sự nên có sẵn trên toàn cầu, bởi vì nó nằm trong liên kết POSIX mà Toby cung cấp. Tuy nhiên, có khá nhiều bộ công cụ không phải POSIX tồn tại ngoài kia.
Kevin

5

Vì không có phần vỏ cụ thể nào được đề cập, đây là cách thực hiện toàn bộ phần zshvỏ:

ls -lhf **/*(.Lk-1024oL)

Các **mô hình toàn cầu phù hợp như* nhưng qua /trong tên đường dẫn, ví dụ như một tìm kiếm đệ quy sẽ làm gì.

Các lslệnh sẽ cho phép kích thước có thể đọc được con người với -h, và định dạng đầu ra danh sách dài với -l. Các-f disable tùy chọn sắp xếp, vì vậy lssẽ chỉ liệt kê các tập tin theo thứ tự chúng được đưa ra.

Thứ tự này được sắp xếp theo **/*(.Lk-1024oL)mẫu hình tròn tên tệp để các tệp nhỏ hơn được liệt kê đầu tiên. Các **/*chút phù hợp với tất cả các tập tin và thư mục trong thư mục này và dưới đây, nhưng (...)Sửa hành vi của glob (đó là một "glob vòng loại").

Đó là oLlúc kết thúc mà đơn đặt hàng ( o) tên bởi kích thước tập tin ( L"chiều dài").

Lúc .bắt đầu làm cho toàn cầu chỉ khớp với các tệp thông thường (không có thư mục).

Các Lk-1024 Selects bit file có kích thước nhỏ hơn 1024 KB ( "chiều dài trong KB ít hơn 1024").

Nếu zshkhông phải là vỏ tương tác chính của bạn, thì bạn có thể sử dụng

zsh -c 'ls -lf **/*(.Lk-1024oL)'

Sử dụng setopt GLOB_DOTS(hoặc zsh -o GLOB_DOTS -c ...) để khớp với các tên ẩn. ... Hoặc chỉ cần thêm Dvào chuỗi vòng loại toàn cầu.


Mở rộng ở trên, giả sử rằng bạn muốn có đầu ra 2 cột với tên đường dẫn và kích thước có thể đọc được của con người, đồng thời giả sử rằng bạn có numfmttừ lõi GNU,

zmodload -F zsh/stat b:zstat

for pathname in **/*(.Lk-1024oL); do
    printf '%s\t%s\n' "$pathname" "$(zstat +size "$pathname" | numfmt --to=iec)"
done

hoặc, nhanh hơn,

paste <( printf '%s\n' **/*(.Lk-1024oL) ) \
      <( zstat -N +size **/*(.Lk-1024oL) | numfmt --to=iec )

4

Nếu bạn sortkhông có -htùy chọn, bạn có thể sử dụng lệnh awk (mặc dù rất dài) như sau:

find . -type f -size -1024k -exec ls -al {} \; | sort -k 5 -n | awk '{if ($5 > 1099511627776) {print $9,$5/1024/1024/1024/1024"T"} else if ($5 > 1073741824) {print $9,$5/1024/1024/1024"G"} else if ($5 > 1048576) {print $9,$5/1024/1024"M"} else if ($5 > 1024) {print $9,$5/1024"K"} else {print $9,$5"B"}}' | column -t

Điều này sẽ sắp xếp đầu ra của bạn theo byte và sau đó chuyển đổi chúng thành kích thước có thể đọc được của con người sau đó.


-1

Điều này sẽ làm việc?

ls -l | awk '{if ($5<=1024) {print}}' | sort -k 5 -n | awk '{print $9"\t"substr($5/1024,1,3)"k"} '| column -t

awkExp đầu tiên sẽ tìm các tệp nhỏ hơn 1M và tệp thứ hai sẽ lấy kích thước byte từ kết quả và chuyển đổi nó thành KB và in 3 phần tử đầu tiên để có kích thước có thể đọc được.


Điều đó không thực sự giải quyết câu hỏi OP - nó chỉ xuất hiện trong thư mục hiện tại và sẽ chỉ in các tệp thông thường. Cũng sẽ so sánh với 1Kb thay vì 1MB. Cuối cùng, chúng tôi sau câu trả lời với một số giải thích về lý do tại sao mã hoạt động.
hóa dầu

Xấu của tôi thêm những gì nó làm.
Vignesh SP
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.