Imprime a lista de arquivos com tamanho de arquivo menor que o especificado

3

Estou tentando criar um script que possa ser executado para pesquisar uma lista de arquivos, comparar o campo de tamanho de arquivo com o tamanho de arquivo especificado e exibir os arquivos menores que o tamanho de arquivo especificado.

Eu entendo que devo usar 'ls -l' para obter uma lista detalhada de arquivos. No entanto, como posso pesquisar a lista e puxar os arquivos?

    
por JVAN 15.03.2017 / 05:41

3 respostas

7

Sua abordagem é desajeitada (e é justa dizer errado ). Existem ferramentas dedicadas para esse tipo de tarefa, find é uma delas.

Por exemplo, para localizar todos os arquivos no diretório atual com menos de 1 MiB (1048576 Bytes), recursivamente:

find . -type f -size -1048576c

Ou com shells que fornecem esses qualifiers glob baseados em tamanho, por exemplo zsh , recursivamente:

print -rl -- **/*(.L-1048576)

Aqui, ao contrário de find acima, sem os arquivos ocultos. Adicione o qualificador D glob para incluí-los.

    
por 15.03.2017 / 05:47
3

Coisas a ter em conta ao analisar a saída de ls -l :

  • o formato depende da localidade. O formato é especificado apenas pelo POSIX no código do idioma POSIX / C e, mesmo assim, permite algumas variações (como a quantidade de espaçamento entre os campos, a largura do primeiro campo ...). Por exemplo, você não pode detectar facilmente nomes de arquivos portáveis que começam com caracteres em branco.
  • Muitos sistemas permitem espaços em branco em nomes de usuários e grupos, tornando quase impossível a análise da saída de maneira confiável. O melhor é usar ls -n (para usar IDs de usuário numéricos) em vez de ls -l .
  • É impossível analisar a saída de ls de forma confiável se os nomes dos arquivos puderem conter caracteres de nova linha (e a nova linha for permitida em um nome de arquivo em praticamente todos os sistemas POSIX), a menos que você use a opção -q Diga o nome exato do arquivo, apenas veja uma representação citada a partir da qual você não pode voltar ao nome original do arquivo) ou use opções não-padrão encontradas em algumas implementações. Embora veja também o truque abaixo.
  • O campo tamanho não é fornecido para todos os tipos de arquivos (e o significado do campo tamanho varia entre sistemas para alguns tipos de arquivos). Você provavelmente deseja limitar a arquivos regulares.
  • O acima está assumindo um POSIX ls . Sabe-se que versões antigas têm formatos de saída diferentes ou espaços em branco ausentes entre campos em algumas circunstâncias ...

Então, com isso em mente, desde que você possa garantir que os nomes de arquivo não contenham caracteres de nova linha e não inicie com caracteres em branco, para listar os arquivos regulares cujo tamanho é estritamente menor que 1 MiB, você poderia: / p>

(
  export LC_ALL=C
  ls -n | awk '
    /^-/ && $5 < 1048576 { 
      gsub(/([^[:blank:]]+[[:blank:]]+){8}/, "")
      print
    }'
)

Adicione a opção -a se você quiser incluir arquivos ocultos. Adicione -L se para links simbólicos, você quer considerar o arquivo que eles (eventualmente) resolverão.

Como outros disseram, a solução correta seria usar find aqui.

Truque para evitar a nova linha e o principal problema em branco.

Se em vez de ls -n , usamos ls -nd ./* , poderíamos saber onde o nome do arquivo começa (em ./ ) e em qual linha ele termina (na linha antes do próximo ./ ) , então você poderia fazer:

(
  export LC_ALL=C
  ls -nd ./* | awk '
    /\// {
      selected = (/^-/ && $5 < 1048576)
      sub(/.*\//, "./")
    }
    selected'
)

No entanto, observe que não funcionará se houver um grande número de arquivos no diretório atual, pois o ./* é expandido pelo shell e isso pode fazer com que o limite do número de argumentos seja alcançado.

Para incluir arquivos ocultos, -a não ajudará aqui, precisamos informar ao shell para expandi-los. POSIXly, é um pouco complicado:

ls -dn ./..?* ./.[!.]* ./*

(que provavelmente causará mensagens de aviso sobre arquivos ./..?* ou ./.[!.]* ausentes).

    
por 15.03.2017 / 09:05
1

Como você só deseja analisar ls's output, poderá encontrar os regular files que são menores em tamanho do que o limite superior ( MAX bytes ) e ASSUMING no whitespace / newlines nos seus nomes de arquivos que você poderia fazer o seguinte:

/bin/ls -l | awk -v MAX=150 '/^-/ && $5 <= MAX { print $NF }'
    
por 15.03.2017 / 07:28