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