Como faço para que o comando find imprima o tamanho do arquivo com o nome do arquivo?


106

Se eu emitir o comando find da seguinte maneira:

$ find . -name *.ear

Ele imprime:

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

O que eu quero 'imprimir' na linha de comando é o nome e o tamanho:

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

Respostas:


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

apenas um extra da resposta de jer.drab.org. economiza tempo convertendo mentalmente para MB;)


8
Esta versão executará o processo "ls" para cada arquivo. Se você tiver muitos arquivos (digamos, mais de mil), é melhor otimizá-los com: find . -name '*.ear' -exec ls -lh {} + \;(extensão GNU) ou find . -name '*.ear' -print0 | xargs -0 ls -lh. Além disso, você pode adicionar -type fse estiver interessado apenas em arquivos (ou adicionar -da ls se quiser que os próprios diretórios sejam incluídos sem seu conteúdo).
ash108

2
Sua resposta não exclui diretórios, portanto, você também executará ls em diretórios, o que claramente não é a coisa certa a se fazer.
Faheem Mitha

2
Esta é uma maneira realmente ineficiente de fazer as coisas - e infelizmente os comentários do ash108 também não são ideais. É muito melhor usar a opção -printf para localizar.
oskarpearson

A resposta do dmazzoni é muito mais eficiente porque evita um fork + exec em cada arquivo (100x mais rápido na minha máquina). Tive que mudar% k para% s. @FaheemMitha: você pode adicionar opções como -type fcontar apenas arquivos regulares.
Sr. Fooz

A solução fácil @FaheemMitha é find . -name "*.ear" -type fpara arquivos. -type dfunciona para diretórios.
anon58192932

111

Você precisa usar -exec ou -printf. Printf funciona assim:

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

-exec é mais poderoso e permite que você execute comandos arbitrários - então você pode usar uma versão de 'ls' ou 'wc' para imprimir o nome do arquivo junto com outras informações. 'man find' mostrará os argumentos disponíveis para printf, que pode fazer muito mais do que apenas o tamanho do arquivo.

[editar] -printf não está no padrão POSIX oficial, então verifique se ele é compatível com sua versão. No entanto, a maioria dos sistemas modernos usará GNU find ou uma versão estendida de forma semelhante, então há uma boa chance de que seja implementado.


Parece que seu exemplo é mais preciso, mas não consigo fazer com que o exemplo funcione no Solaris 10.
Brian,

Infelizmente, o Solaris find não oferece suporte a -printf: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Você pode instalar o GNU find se for incomodado; caso contrário, será necessário usar exec ou | como sugerido por outros.
Leigh Caldwell,

1
+1 Isso parece mais limpo. Para formatar a saída, prefiro adicionar o columncomando. find . -name *.ear -printf "%p %k KB\n" | column -t
Amol

1
Esta resposta é uma maneira muito mais correta de fazer isso do que a resposta aceita
ameaçadoramente

2
A -printfopção não funciona no OS X também. Consulte stackoverflow.com/questions/752818/… .
abeboparebop

33

uma solução simples é usar a opção -ls em find:

find . -name \*.ear -ls

Isso dá a você cada entrada no formato normal "ls -l". Ou, para obter a saída específica que você parece estar procurando, isto:

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

O que fornecerá o nome do arquivo seguido pelo tamanho em KB.


Nem sabia de uma lsopção, isso deveria estar muito mais alto na lista de respostas do que é.
Prometheus de

24

Usando gnu find, acho que é isso que você quer. Ele encontra todos os arquivos reais e não os diretórios (-type f), e para cada um imprime o nome do arquivo (% p), uma guia (\ t), o tamanho em kilobytes (% k), o sufixo "KB" e então uma nova linha (\ n).

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

Se o comando printf não formatar as coisas da maneira que você deseja, você pode usar exec, seguido pelo comando que deseja executar em cada arquivo. Use {} para o nome do arquivo e termine o comando com um ponto e vírgula (;). Na maioria dos shells, todos os três desses caracteres devem ser escapados com uma barra invertida.

Aqui está uma solução simples que os encontra e os imprime usando "ls -lh", que mostrará o tamanho em formato legível (k para kilobytes, M para megabytes):

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

Como outra alternativa, "wc -c" imprimirá o número de caracteres (bytes) no arquivo:

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

+1 Exceto por ter omitido -name '*.ear'nos exemplos, esta deve ser a resposta nº 1. Ele responde à pergunta com precisão, explica o significado da sintaxe e oferece várias alternativas.
OsakaWebbie

esta deve ser uma resposta aceita, pois não executa um novo comando para cada linha, portanto, é muito mais rápido do que o atualmente aceito por shyam
jirislav

Na verdade, esta deve ser a resposta certa. Além disso, find . -type f -printf '%k KB\t %p\n'ou seja, imprimir o tamanho do arquivo primeiro, provavelmente será uma saída melhor em termos de formatação devido ao alinhamento.
myradio

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

Isso dá a você apenas o tamanho do arquivo, em vez de todas as coisas desnecessárias.


wcfunciona melhor para isso, se você precisar do tamanho em bytes.
Alex

4

Awk pode consertar a saída para fornecer exatamente o que o questionador pediu. No meu sistema Solaris 10, encontre -ls tamanho das impressões em KB como o segundo campo, portanto:

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

Caso contrário, use -exec ls -lh e selecione o campo de tamanho da saída. Novamente no 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

Por que não usar du -a ? Por exemplo

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

Funciona em um Mac


3

Tive dificuldade com isso no Mac OS X, onde o comando find não é compatível -printf.

Uma solução que encontrei, que confia reconhecidamente no 'grupo' para todos os arquivos serem 'equipe' foi ...

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

Isso divide a saída ls long em três tokens

  1. as coisas antes do texto 'pessoal'
  2. o tamanho do arquivo
  3. o nome do arquivo

E então gera os tokens 2 e 3, ou seja, a saída é o número de bytes e o nome do arquivo

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

1
Útil saber .. A versão GNU do findestá disponível através do homebrew combrew install findutils
mwfearnley

2

Isso deve fornecer o que você está procurando, incluindo a formatação (ou seja, o nome do arquivo primeiro e o tamanho depois):

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

saída de amostra (onde costumava -iname "*.php"obter alguns resultados):

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

Você pode tentar isto:

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

Isso lhe dará o tamanho em bytes. Mas o comando du também aceita os parâmetros -k para KB e -m para MB. Isso lhe dará uma saída como

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



1

Experimente os seguintes comandos:

GNU stat:

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

BSD stat:

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

no entanto, statnão é padrão, então duou wcpoderia ser uma abordagem melhor:

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


0

Se você precisa obter o tamanho total, aqui está uma proposta de script

#!/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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.