Bagaimana cara mendapatkan perintah find untuk mencetak ukuran file dengan nama file?

106

Jika saya mengeluarkan perintah find sebagai berikut:

$ find . -name *.ear

Ini mencetak:

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

Yang ingin saya 'cetak' ke baris perintah adalah nama dan ukurannya:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB
Brian Hart
sumber

Jawaban:

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

hanya ekstra dari balasan jer.drab.org. menghemat waktu untuk mengubah ke MB secara mental;)

malu
sumber
8
Versi ini akan menjalankan proses "ls" untuk setiap file. Jika Anda memiliki banyak file (katakanlah, lebih dari seribu) sebaiknya Anda mengoptimalkannya dengan: find . -name '*.ear' -exec ls -lh {} + \;(ekstensi GNU) atau find . -name '*.ear' -print0 | xargs -0 ls -lh. Anda juga mungkin ingin menambahkan -type fjika Anda hanya tertarik pada file (atau menambahkan -dke ls jika Anda ingin direktori itu sendiri disertakan tanpa isinya).
ash108
2
Jawaban Anda tidak mengecualikan direktori, jadi Anda juga akan menjalankan ls di direktori, yang jelas bukan hal yang benar untuk dilakukan.
Faheem Mitha
2
Ini adalah cara yang sangat tidak efisien untuk melakukan sesuatu - dan sayangnya komentar ash108 juga tidak ideal. Jauh lebih baik menggunakan opsi -printf untuk menemukan.
oskarpearson
Jawaban dmazzoni jauh lebih efisien karena menghindari fork + exec pada setiap file (100x lebih cepat di mesin saya). Saya harus mengubah% k menjadi% s. @FaheemMitha: Anda dapat menambahkan opsi seperti -type fhanya menghitung file biasa.
Tuan Fooz
Solusi mudah @FaheemMitha adalah find . -name "*.ear" -type funtuk file. -type dbekerja untuk direktori.
anon58192932
111

Anda perlu menggunakan -exec atau -printf. Printf bekerja seperti ini:

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

-exec lebih kuat dan memungkinkan Anda menjalankan perintah sewenang-wenang - sehingga Anda dapat menggunakan versi 'ls' atau 'wc' untuk mencetak nama file bersama dengan informasi lainnya. 'man find' akan menunjukkan argumen yang tersedia untuk printf, yang dapat melakukan lebih dari sekadar ukuran file.

[edit] -printf tidak ada dalam standar POSIX resmi, jadi periksa apakah itu didukung pada versi Anda. Namun, kebanyakan sistem modern akan menggunakan GNU find atau versi serupa yang diperluas, jadi ada kemungkinan besar ini akan diterapkan.

Leigh Caldwell
sumber
Sepertinya contoh Anda lebih tepat, tetapi saya tidak bisa mendapatkan contoh untuk bekerja pada Solaris 10.
Brian
Saya khawatir Solaris menemukan tidak mendukung -printf sama sekali: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Anda dapat menginstal GNU jika Anda merasa terganggu, jika tidak, Anda perlu menggunakan exec atau | seperti yang disarankan oleh orang lain.
Leigh Caldwell
1
+1 Sepertinya lebih bersih. Untuk memformat keluaran saya lebih suka menambahkan columnperintah. find . -name *.ear -printf "%p %k KB\n" | column -t
Amol
1
Jawaban ini adalah cara yang jauh lebih tepat untuk melakukannya daripada jawaban yang diterima
mengancam
2
The -printfpilihan tidak bekerja di OS X baik. Lihat stackoverflow.com/questions/752818/… .
abeboparebop
33

solusi sederhana adalah dengan menggunakan opsi -ls di find:

find . -name \*.ear -ls

Itu memberi Anda setiap entri dalam format "ls -l" normal. Atau, untuk mendapatkan hasil spesifik yang sepertinya Anda cari, ini:

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

Yang akan memberi Anda nama file diikuti dengan ukuran dalam KB.

Michael Cramer
sumber
Bahkan tidak mengetahui sebuah lsopsi, ini seharusnya jauh lebih tinggi dalam daftar jawaban daripada yang sebenarnya.
Prometheus
24

Menggunakan gnu find, saya rasa inilah yang Anda inginkan. Ia menemukan semua file nyata dan bukan direktori (-tipe f), dan untuk masing-masing mencetak nama file (% p), tab (\ t), ukuran dalam kilobyte (% k), sufiks "KB", dan kemudian baris baru (\ n).

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

Jika perintah printf tidak memformat hal-hal yang Anda inginkan, Anda dapat menggunakan exec, diikuti dengan perintah yang ingin Anda jalankan pada setiap file. Gunakan {} untuk nama file, dan akhiri perintah dengan titik koma (;). Pada kebanyakan shell, ketiga karakter tersebut harus di-escape dengan garis miring terbalik.

Berikut solusi sederhana yang menemukan dan mencetaknya menggunakan "ls -lh", yang akan menunjukkan ukuran dalam bentuk yang dapat dibaca manusia (k untuk kilobyte, M untuk megabyte):

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

Sebagai alternatif lain, "wc -c" akan mencetak jumlah karakter (byte) dalam file:

find . -type f -exec wc -c \{\} \;
dmazzoni.dll
sumber
+1 Kecuali jika -name '*.ear'contoh dihilangkan , ini seharusnya menjadi jawaban # 1. Ini menjawab pertanyaan dengan tepat, menjelaskan arti sintaksis, dan memberikan banyak alternatif.
OsakaWebbie
ini harus diterima jawaban karena tidak menjalankan perintah baru untuk setiap baris, sehingga jauh lebih cepat daripada yang diterima saat ini dari shyam
jirislav
Memang ini harus menjadi jawaban yang benar. Juga, find . -type f -printf '%k KB\t %p\n'misalnya, mencetak ukuran file terlebih dahulu, kemungkinan besar akan menjadi keluaran yang lebih bagus dalam hal pemformatan karena penyelarasan.
myradio
8
find . -name '*.ear' -exec du -h {} \;

Ini memberi Anda ukuran file saja, bukan semua hal yang tidak perlu.

pengguna2121791
sumber
wcberfungsi untuk ini lebih baik, jika Anda memerlukan ukuran dalam byte.
Alex
4

Awk dapat memperbaiki keluaran untuk memberikan apa yang diminta oleh penanya. Pada sistem Solaris 10 saya, temukan -ls mencetak ukuran dalam KB sebagai kolom kedua, jadi:

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

Jika tidak, gunakan -exec ls -lh dan pilih kolom size dari output. Sekali lagi di 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
tpgould
sumber
4

Mengapa tidak menggunakan du -a ? Misalnya

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

Bekerja di Mac

sietschie
sumber
3

Saya berjuang dengan ini di Mac OS X di mana perintah find tidak mendukung -printf.

Solusi yang saya temukan, yang memang bergantung pada 'grup' untuk semua file menjadi 'staf' adalah ...

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

Ini membagi output panjang menjadi tiga token

  1. hal-hal sebelum teks 'staf'
  2. ukuran file
  3. nama file

Dan kemudian mengeluarkan token 2 dan 3, yaitu keluaran adalah jumlah byte dan kemudian nama file

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php
Mike M
sumber
1
Berguna untuk mengetahui .. Versi GNU findtersedia melalui homebrew denganbrew install findutils
mwfearnley
2

Ini akan memberi Anda apa yang Anda cari, termasuk pemformatan (yaitu nama file pertama dan ukuran sesudahnya):

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

keluaran sampel (di mana saya biasa -iname "*.php"mendapatkan beberapa hasil):

./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
adriano72
sumber
1

Anda bisa mencoba ini:

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

Ini akan memberi Anda ukuran dalam byte. Tetapi perintah du juga menerima parameter -k untuk KB dan -m untuk MB. Ini akan memberi Anda keluaran seperti

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear
Yaba
sumber
1
find . -name "*.ear" | xargs ls -sh
killdash10
sumber
1
$ temukan. -name "test *" -exec du -sh {} \;
4.0K ./test1
0./test2
0./test3
0./test4
$

Referensi Scripter World

penulis skenario
sumber
1

Coba perintah berikut:

GNU stat:

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

BSD stat:

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

Namun stattidak standar, jadi duatau wcbisa menjadi pendekatan yang lebih baik:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'
kenorb
sumber
0
find . -name "*.ear" -exec ls -l {} \;
Jeremy Weathers
sumber
0

Jika Anda perlu mendapatkan ukuran total, berikut adalah proposal skrip

#!/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"
Damien C
sumber