Làm cách nào để lấy lệnh find để in ra kích thước tệp với tên tệp?


106

Nếu tôi phát hành lệnh tìm như sau:

$ find . -name *.ear

Nó in ra:

./dir1/dir2/earFile1.ear
./dir1/dir2/earFile2.ear
./dir1/dir3/earFile1.ear

Những gì tôi muốn 'in' vào dòng lệnh là tên và kích thước:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB

Câu trả lời:


109
find . -name '*.ear' -exec ls -lh {} \;

chỉ là phần h thêm từ câu trả lời của jer.drab.org. tiết kiệm thời gian chuyển đổi sang MB tinh thần;)


8
Phiên bản này sẽ thực hiện quy trình "ls" cho mỗi tệp. Nếu bạn có nhiều tệp (giả sử hơn một nghìn), bạn nên tối ưu hóa tốt hơn bằng cách: find . -name '*.ear' -exec ls -lh {} + \;(phần mở rộng GNU) hoặc find . -name '*.ear' -print0 | xargs -0 ls -lh. Ngoài ra, bạn có thể muốn thêm -type fnếu bạn chỉ quan tâm đến tệp (hoặc thêm -dvào ls nếu bạn muốn bản thân các thư mục được bao gồm mà không có nội dung của chúng).
ash108

2
Câu trả lời của bạn không loại trừ các thư mục, vì vậy bạn cũng sẽ chạy ls trên các thư mục, điều này rõ ràng không phải là điều đúng đắn.
Faheem Mitha

2
Đây là một cách làm thực sự không hiệu quả - và tiếc là nhận xét của ash108 cũng không lý tưởng. Tốt hơn nhiều là sử dụng tùy chọn -printf để tìm.
oskarpearson

Câu trả lời của dmazzoni hiệu quả hơn nhiều vì nó tránh được fork + thực thi trên mọi tệp (nhanh hơn 100 lần trên máy của tôi). Tôi đã phải thay đổi% k thành% s. @FaheemMitha: bạn có thể thêm các tùy chọn như -type fchỉ đếm các tệp thông thường.
Mr Fooz

@FaheemMitha giải pháp dễ dàng find . -name "*.ear" -type fdành cho các tệp. -type dhoạt động cho các thư mục.
anon58192932

111

Bạn cần sử dụng -exec hoặc -printf. Printf hoạt động như thế này:

find . -name *.ear -printf "%p %k KB\n"

-exec mạnh hơn và cho phép bạn thực hiện các lệnh tùy ý - vì vậy bạn có thể sử dụng phiên bản 'ls' hoặc 'wc' để in ra tên tệp cùng với các thông tin khác. 'man find' sẽ hiển thị cho bạn các đối số có sẵn cho printf, có thể làm được nhiều việc hơn là chỉ kích thước tệp.

[sửa] -printf không có trong tiêu chuẩn POSIX chính thức, vì vậy hãy kiểm tra xem nó có được hỗ trợ trên phiên bản của bạn không. Tuy nhiên, hầu hết các hệ thống hiện đại sẽ sử dụng GNU find hoặc một phiên bản mở rộng tương tự, vì vậy rất có thể nó sẽ được triển khai.


Có vẻ như ví dụ của bạn chính xác hơn, nhưng tôi dường như không thể lấy ví dụ này để hoạt động trên Solaris 10.
Brian

Tôi e rằng Solaris thấy không hỗ trợ -printf chút nào: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Bạn có thể cài đặt GNU, tìm nếu bạn có thể bị làm phiền, nếu không, bạn cần sử dụng tệp thi hành hoặc | theo gợi ý của những người khác.
Leigh Caldwell

1
+1 Điều này có vẻ sạch hơn. Để định dạng đầu ra, tôi muốn thêm columnlệnh. find . -name *.ear -printf "%p %k KB\n" | column -t
Amol

1
Câu trả lời này là một cách nhiều chính xác hơn để làm điều đó hơn là câu trả lời được chấp nhận
với vẻ đe dọa

2
Các -printftùy chọn không hoạt động trong OS X một trong hai. Xem stackoverflow.com/questions/752818/… .
abeboparebop

33

một giải pháp đơn giản là sử dụng tùy chọn -ls trong tìm:

find . -name \*.ear -ls

Điều đó cung cấp cho bạn mỗi mục nhập ở định dạng "ls -l" thông thường. Hoặc, để có được đầu ra cụ thể mà bạn dường như đang tìm kiếm, hãy làm như sau:

find . -name \*.ear -printf "%p\t%k KB\n"

Điều này sẽ cung cấp cho bạn tên tệp theo sau là kích thước tính bằng KB.


Thậm chí không biết về một lstùy chọn, điều này sẽ cao hơn nhiều trong danh sách các câu trả lời so với nó.
Prometheus

24

Sử dụng gnu find, tôi nghĩ đây là những gì bạn muốn. Nó tìm thấy tất cả các tệp thực chứ không phải thư mục (-type f), và đối với mỗi tệp in tên tệp (% p), tab (\ t), kích thước tính bằng kilobyte (% k), hậu tố "KB", sau đó một dòng mới (\ n).

find . -type f -printf '%p\t%k KB\n'

Nếu lệnh printf không định dạng mọi thứ theo cách bạn muốn, bạn có thể sử dụng lệnh execute, sau đó là lệnh bạn muốn thực thi trên mỗi tệp. Sử dụng {} cho tên tệp và kết thúc lệnh bằng dấu chấm phẩy (;). Trên hầu hết các shell, cả ba ký tự đó phải được thoát bằng dấu gạch chéo ngược.

Đây là một giải pháp đơn giản để tìm và in chúng ra bằng cách sử dụng "ls -lh", sẽ hiển thị cho bạn kích thước ở dạng con người có thể đọc được (k cho kilobyte, M cho megabyte):

find . -type f -exec ls -lh \{\} \;

Như một giải pháp thay thế khác, "wc -c" sẽ in số ký tự (byte) trong tệp:

find . -type f -exec wc -c \{\} \;

+1 Ngoại trừ việc bỏ qua -name '*.ear'trong các ví dụ, đây sẽ là câu trả lời số 1. Nó trả lời chính xác câu hỏi, giải thích ý nghĩa của cú pháp và đưa ra nhiều lựa chọn thay thế.
OsakaWebbie

điều này nên được câu trả lời được chấp nhận vì nó không chạy lệnh mới cho mỗi dòng, do đó nó là nhiều hơn nữa nhanh hơn so với một hiện chấp nhận từ Shyam
jirislav

Quả thực đây phải là câu trả lời đúng. Ngoài ra, find . -type f -printf '%k KB\t %p\n'tức là, in kích thước tệp trước, rất có thể sẽ có kết quả đẹp hơn về định dạng do căn chỉnh.
myradio

8
find . -name '*.ear' -exec du -h {} \;

Điều này chỉ cung cấp cho bạn kích thước tệp, thay vì tất cả những thứ không cần thiết.


wchoạt động cho điều này tốt hơn, nếu bạn cần kích thước tính bằng byte.
Alex,

4

Awk có thể sửa kết quả đầu ra để cung cấp những gì người hỏi yêu cầu. Trên hệ thống Solaris 10 của tôi, tìm kích thước bản in -ls tính bằng KB làm trường thứ hai, vì vậy:

% find . -name '*.ear' -ls | awk '{print $2, $11}'
5400 ./dir1/dir2/earFile2.ear
5400 ./dir1/dir2/earFile3.ear
5400 ./dir1/dir2/earFile1.ear

Nếu không, hãy sử dụng -exec ls -lh và chọn trường kích thước từ đầu ra. Một lần nữa trên Solaris 10:

% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}'
5.3M ./dir1/dir2/earFile2.ear
5.3M ./dir1/dir2/earFile3.ear
5.3M ./dir1/dir2/earFile1.ear

4

Tại sao không sử dụng du -a ? Ví dụ

find . -name "*.ear" -exec du -a {} \;

Hoạt động trên máy Mac


3

Tôi đã vật lộn với điều này trên Mac OS X trong đó lệnh tìm không hỗ trợ -printf .

Một giải pháp mà tôi đã tìm thấy, thừa nhận rằng dựa vào 'nhóm' cho tất cả các tệp là 'nhân viên' là ...

ls -l -R | sed 's/\(.*\)staff *\([0-9]*\)..............\(.*\)/\2 \3/'

Điều này chia đầu ra dài ls thành ba mã thông báo

  1. những thứ trước văn bản 'staff'
  2. kích thước tệp
  3. tên tập tin

Và sau đó xuất ra các mã thông báo 2 và 3, tức là đầu ra là số byte và sau đó là tên tệp

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php

1
Thông tin hữu ích cần biết .. Phiên bản GNU của findcó sẵn thông qua homebrew vớibrew install findutils
mwfearnley

2

Điều này sẽ cung cấp cho bạn những gì bạn đang tìm kiếm, bao gồm định dạng (tức là tên tệp đầu tiên và kích thước sau đó):

find . -type f -iname "*.ear" -exec du -ah {} \; | awk '{print $2"\t", $1}'

đầu ra mẫu (nơi tôi đã sử dụng -iname "*.php"để lấy một số kết quả):

./plugins/bat/class.bat.inc.php  20K
./plugins/quotas/class.quotas.inc.php    8.0K
./plugins/dmraid/class.dmraid.inc.php    8.0K
./plugins/updatenotifier/class.updatenotifier.inc.php    4.0K
./index.php      4.0K
./config.php     12K
./includes/mb/class.hwsensors.inc.php    8.0K

1

Bạn có thể thử điều này:

find. -name *.ear -exec du {} \;

Điều này sẽ cung cấp cho bạn kích thước tính bằng byte. Nhưng lệnh du cũng chấp nhận các tham số -k cho KB và -m cho MB. Nó sẽ cung cấp cho bạn một đầu ra như

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear



1

Hãy thử các lệnh sau:

GNU stat:

find . -type f -name *.ear -exec stat -c "%n %s" {} ';'

BSD stat:

find . -type f -name *.ear -exec stat -f "%N %z" {} ';'

tuy nhiên statkhông phải là tiêu chuẩn, vì vậy duhoặc wccó thể là một cách tiếp cận tốt hơn:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'


0

Nếu bạn cần lấy tổng kích thước, đây là một đề xuất tập lệnh

#!/bin/bash
totalSize=0

allSizes=`find . -type f -name *.ear -exec stat -c "%s" {} \;`

for fileSize in $allSizes; do
    totalSize=`echo "$(($totalSize+$fileSize))"`
done
echo "Total size is $totalSize bytes"
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.