Як отримати команду find, щоб роздрукувати розмір файлу з ім'ям файлу?


106

Якщо я видаю команду find так:

$ find . -name *.ear

Він виводить:

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

Що я хочу "надрукувати" в командному рядку, це ім'я та розмір:

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

Відповіді:


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

лише ч. додаткової відповіді на відповідь jer.drab.org. економить час, перетворюючись на МБ подумки;)


8
Ця версія буде виконувати "ls" процес для кожного файлу. Якщо у вас багато файлів (скажімо, понад тисячу), то краще оптимізувати це за допомогою: find . -name '*.ear' -exec ls -lh {} + \;(розширення GNU) або find . -name '*.ear' -print0 | xargs -0 ls -lh. Крім того, ви можете додати, -type fякщо вас цікавлять лише файли (або додати -dдо ls, якщо ви хочете, щоб самі каталоги були включені без їх вмісту).
— ash108

2
Ваша відповідь не виключає каталогів, тому ви в кінцевому підсумку запустите ls і в каталогах, що, очевидно, не правильно.
— Faheem Mitha

2
Це дійсно неефективний спосіб робити речі - і, на жаль, коментарі ash108 також не є ідеальними. Набагато краще використовувати параметр -printf, щоб знайти.
— oskarpearson

Відповідь dmazzoni набагато ефективніше, тому що вона уникає fork + exec у кожному файлі (на 100 разів швидше на моїй машині). Мені довелося змінити% k на% s. @FaheemMitha: ви можете додавати параметри, як, наприклад, -type fпідраховувати лише звичайні файли.
— Містер Фооз

@FaheemMitha просте рішення find . -name "*.ear" -type fдля файлів. -type dпрацює для каталогів.
— anon58192932

111

Вам потрібно використовувати -exec або -printf. Printf працює так:

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

-exec є більш потужним і дозволяє виконувати довільні команди - тому ви можете використовувати версію 'ls' або 'wc' для друку імені файлу разом з іншою інформацією. 'man find' покаже вам доступні аргументи для printf, що може зробити набагато більше, ніж просто розмір файлів.

[edit] -printf не є офіційним стандартом POSIX, тому перевірте, чи підтримується він у вашій версії. Однак більшість сучасних систем використовуватимуть GNU find або аналогічно розширену версію, тому є хороший шанс, що вона буде реалізована.


Схоже, ваш приклад є більш точним, але я не можу отримати приклад для роботи над Solaris 10.
— Брайан,

Я боюся, що пошук Solaris взагалі не підтримує -printf: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Ви можете встановити GNU find, якщо вас можуть турбувати, інакше вам потрібно використовувати exec або | як пропонують інші.
— Лі Колдвелл

1
+1 Це здається більш чистим. Для форматування виводу я вважаю за краще додати columnкоманду. find . -name *.ear -printf "%p %k KB\n" | column -t
— Амол

1
Ця відповідь є набагато правильнішим способом, ніж прийнята відповідь
— грізно

2
-printfОпція не працює в OS X або. Дивіться stackoverflow.com/questions/752818/… .
— abeboparebop

33

простим рішенням є використання параметра -ls у знаходженні:

find . -name \*.ear -ls

Це дає вам кожен запис у звичайному форматі "ls -l". Або для отримання конкретного результату, який, здається, ви шукаєте, це:

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

Це дасть вам ім'я файлу з наступним розміром у КБ.


Навіть не знали про lsваріант, це повинно бути набагато вище в списку відповідей, ніж є.
— Прометей

24

Використовуючи gnu find, я думаю, що саме цього ви хочете. Він знаходить усі реальні файли, а не каталоги (-тип f), і для кожного друкується ім'я файлу (% p), вкладка (\ t), розмір у кілобайтах (% k), суфікс "KB", а потім новий рядок (\ n).

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

Якщо команда printf не форматує речі так, як вам потрібно, ви можете використовувати exec, а потім команду, яку потрібно виконати для кожного файлу. Використовуйте {} для імені файлу та завершіть команду крапкою з комою (;). На більшості оболонок всі три символи повинні бути уникнуті зворотним нахилом.

Ось просте рішення, яке знаходить і роздруковує їх за допомогою "ls -lh", яке покаже вам розмір у читаному для людини вигляді (k для кілобайт, M для мегабайт):

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

Як ще одна альтернатива, "wc -c" надрукує кількість символів (байтів) у файлі:

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

+1 За винятком того, що -name '*.ear'у прикладах пропущено , це має бути відповідь №1. Він відповідає на запитання точно, пояснює значення синтаксису та дає безліч альтернатив.
— OsakaWebbie

на це слід прийняти відповідь, оскільки він не запускає нову команду для кожного рядка, таким чином, це набагато швидше, ніж прийнятий на даний момент від shyam
— jirislav

Дійсно, це має бути правильна відповідь. Крім того, find . -type f -printf '%k KB\t %p\n'тобто надрукувати розмір файлу спочатку, швидше за все, буде приємніше виводитись з точки зору форматування завдяки вирівнюванню.
— myradio

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

Це дає вам лише розмір файлів, а не всі непотрібні речі.


wcпрацює для цього просто краще, якщо вам потрібен розмір у байтах.
— Алекс

4

Awk може виправити вихід, щоб дати лише те, що запитував запитувач. У моїй системі Solaris 10 знайдіть -ls друкує розмір у КБ як друге поле, так що:

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

В іншому випадку використовуйте -exec ls -lh і виберіть поле розміру з виводу. Знову на 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

Чому б не використовувати du -a ? Напр

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

Працює на Mac


3

Я боровся з цим на Mac OS X, де команда find не підтримує -printf.

Я знайшов рішення, яке, мабуть, покладається на "групу" для всіх файлів, які є "співробітниками", було ...

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

Це розбиває ls довгий вихід на три лексеми

  1. матеріал перед текстом "персонал"
  2. розмір файлу
  3. ім'я файлу

А потім виводить лексеми 2 і 3, тобто вихід - це кількість байтів, а потім ім'я файлу

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

1
Корисно знати .. Версія GNU findдоступна через домашню мову зbrew install findutils
— mwfearnley

2

Це має отримати те, що ви шукаєте, включаючи форматування (тобто ім'я файлу спочатку та розмір згодом):

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

вибір вибірки (де я -iname "*.php"отримував певний результат):

./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

Ви можете спробувати це:

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

Це дасть вам розмір у байтах. Але команда du також приймає параметри -k для KB і -m для MB. Це дасть вам такий вихід

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



1

Спробуйте виконати наступні команди:

GNU stat:

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

BSD stat:

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

проте statне є стандартним, так duі wcможе бути кращим підходом:

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


0

Якщо вам потрібно отримати загальний розмір, ось пропозиція щодо сценарію

#!/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"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.