Exibe arquivos para tamanho com limite inferior e superior sem usar 'find'

3

Eu preciso criar um programa via vim no Linux chamado between . O script usa dois argumentos como o limite inferior e superior do tamanho do arquivo e imprime uma lista de nomes de arquivos, bem como seus tamanhos. No entanto, não posso usar o comando find para concluir este script.

Eu cheguei até aqui: para exibir todos os arquivos; mas parece que não consigo exibir dados específicos SEM find .

#!/bin/bash

for i in *
do
    set -- $(ls -l "$i")
    echo $i: $5 bytes
done
    
por Phantom1421 02.05.2016 / 19:18

3 respostas

2

Você poderia:

  • Para verificar o intervalo, você pode usar uma instrução if ou continue :

    if [[ $z -ge $1 || $z -le $2 ]]
    then
        : print result
    fi
    

    ou

    [[ $z -lt $1 || $z -gt $2 ]] && continue
    : print result
    
  • Dependendo das necessidades, as opções de teste são:

    • -ge : maior que ou igual a
    • -le : menor ou igual a
    • -lt : menor que
    • -gt : maior que
  • Use stat , du ou ls para obter o tamanho. Os dois últimos exigiriam uma verificação para ver se o destino também é um diretório ou arquivo regular:

    if [[ -f "$f" ]]
    then
        : a regular file
    fi
    

    ou, para evitar o aninhamento de if's:

    ! [[ -f "$f" ]] && continue
    

    com tamanhos de arquivo, por exemplo:

    z=$(stat -c%s "$f")
    z=$(du -b "$f" | cut -f1)
    z=$(ls -l "$f" | cut -d' ' -f5)
    
  • Para imprimir o resultado, você pode usar printf para obter uma impressão mais limpa. Ou seja fixo com tamanho etc. Leia também isto.

  • Se você realmente quer ser legal, valide os argumentos também ...

#!/bin/bash

usage()
{
    printf "Usage: %s <min-size> <max-size>\n" "$0" >&2
    exit 1
}

! [[ "$1" =~ ^[0-9]+$ ]] && usage
! [[ "$2" =~ ^[0-9]+$ ]] && usage


for f in *
do
    z=$(stat -c%s "$f")

    # Alternatives to get size:
    # ! [[ -f "$f" ]] && continue
    # z=$(du -b "$f" | cut -f1)
    # z=$(ls -l "$f" | cut -d' ' -f5)

    if [[ $z -ge $1 || $z -le $2 ]]
    then
        printf "%11d %s\n" "$z" "$f"
    fi
done
    
por 02.05.2016 / 20:20
2
for i in *
do
  size=$(stat --format="%s" "$i")
  if [ $size -gt $1 -a $size -lt $2 ]
  then
    printf "Right-sized: %s\n" "$i"
  else
    printf "Wrong-sized: %s\n" "$i"
  fi
done

Esta é apenas uma atualização para o seu loop, mas ao invés de analisar ls, ele usa stat para coletar o tamanho do arquivo, em bytes.

Este fragmento assume que você já verificou $ 1 e $ 2 com sanidade - eu não queria fazer todos o seu trabalho de casa para você!

    
por 02.05.2016 / 20:19
2

O que você precisa é de uma condição, que no shell tem a seguinte sintaxe:

if TEST
then
    ACTION
else
    ACTION
fi

Para testes, é comum empregar [ . Por exemplo, para verificar se $5 é maior que 25, mas menor que 50, você escreverá:

if [ "$5" -gt 25 ] && [ "$5" -lt 50 ]
then
    echo "It's greater than 25 but is less than 50"
else
    echo "It's either <= 25, or >= 50, or not a number at all"
fi

Não esqueça as citações (obrigado @Wildcard pelo lembrete) e não passe [ mais que quatro argumentos (obrigado @Jeff Schaller pelo link.)

Confira o Guia do Bash para iniciantes e Guia Avançado de Script Bash , eles são uma boa referência.

(Note, porém, que existem shells além do Bash, e sua sintaxe e capacidades podem ser diferentes.)

    
por 02.05.2016 / 19:28