Usando o awk para processar saídas ls com espaços em nomes de arquivos / caminhos

1

Todos,
Eu tenho um script em que eu uso o comando find para filtrar todos os arquivos png em uma determinada pasta e listá-los junto com seu tamanho. Eu quero a saída no seguinte formato:

 someFile.png => 1.2K 

Estou usando o awk para buscar $ 5 (tamanho do arquivo em formato amigável) e $ 9 (caminho). Aqui está o que estou usando atualmente:

 find "$somePath"  -iname "*.png" -print0 | xargs -0 ls -lh  | awk '{print $9,"=>",$5}'

Às vezes, os nomes dos arquivos ou os caminhos têm espaços e isso desvia o script. Aqui está um exemplo de saída:
    / Users / test / Desktop / Test / image1 = > 1,2K
    /Users/test/Desktop/Test/image1.png = > 1,4 K

A primeira entrada na saída é um arquivo chamado "image1 test.png". Eu li em algum lugar que não se deve analisar a saída ls. Qual é a melhor maneira de resolver isso?

    
por smokinguns 25.04.2012 / 23:31

3 respostas

1

Geralmente, pode ser feito um achado para fazer o que você quer usando exec em vez de enviar a saída para outros programas.

find "$somePath" -iname "*.png" -printf '%p => %s\n'

Se você realmente precisa de tamanhos compatíveis com humanos, é um pouco mais complicado:

find "$somePath" -iname "*.png" -exec printf '{} => ' \; -exec sh -c 'ls -sh "{}" | cut -f1 -d\  ' \;

Observe que o último está analisando ls , mas, até onde eu sei, é impossível que um espaço apareça na primeira coluna; já que estamos apenas pegando a primeira coluna aqui, e porque estamos operando com uma única entrada de cada vez (não uma lista), tudo bem. Caso contrário, você pode usar algum outro programa para mostrar o tamanho. No BSD e no Linux, você pode usar stat ; no Solaris, você pode ter que escrever seu próprio programa para gerar apenas o tamanho de um arquivo.

A parte importante é que você sempre pode usar find para executar o que quiser, passando nomes completos de arquivos - desta forma você não está tentando extrair nomes de arquivos de uma lista que não faz. t tem bons delimitadores.

    
por 25.04.2012 / 23:56
0

A maneira mais conveniente é usar printf from find, mas não tem exatamente a opção que você está procurando. % k imprime o tamanho em K, mas o tamanho, alocado no disco, dependendo das configurações, pode ser sempre um múltiplo de 4k (como no meu sistema) ou algo similar:

find  -name "C*.png" -printf "%f => %k \n"

CalculatorVergleich.png => 28 
ClassifierImage.png => 8 
ClassifierImage.png => 8 

Existe uma opção com tamanho em bytes:

find  -name "C*.png" -printf "%f => %s \n"
CalculatorVergleich.png => 26256 
ClassifierImage.png => 6313 
ClassifierImage.png => 6473 

E existe o% b para blocos 512b ocupados:

find  -name "C*.png" -printf "%f => %b  \n" 
CalculatorVergleich.png => 56  
ClassifierImage.png => 16  
ClassifierImage.png => 16  

Talvez seja útil para você? Não deve ter problemas com espaços em branco em nomes de arquivos.

    
por 26.04.2012 / 04:15
0

Eu suponho que você queira usar o awk para processar ls -l para as informações adicionais que o ls -l fornece. Em geral, find e stat fornecem um resultado mais reproduzível, mas sinta-se à vontade para usar ls.

Uma das coisas legais que ls -l faz, é que tem uma largura fixa, portanto você pode usar substr para o início da linha, então não especificar o comprimento, que incluirá todos os caracteres até o final do arquivo. linha.

No meu exemplo abaixo, atribuo o nome do arquivo a uma string e, em seguida, substituo os espaços por underscores. Eu costumo realizar uma análise mais aprofundada com o awk, então limpar os espaços dos nomes dos arquivos torna a análise mais fácil, e o resultado final vai para os humanos.

$ ls -al | awk '{myfilename=substr($0, 57);gsub(/ /,"_",myfilename);print myfilename}'

Com o find eu normalmente rastreio um sistema de arquivos em um processo de várias horas, e salvo as estatísticas de todos os arquivos, depois pego os campos-chave para análise posterior.

myPath="./"
find "$myPath" -type f  -print0  |  xargs -0 stat   -c"%W %w %Y %y %X %x %9s %n" > myTemp.txt
cat myTemp.txt | awk '{myfilename=substr($0, 152);gsub(/ /,"_",myfilename);printf "%s %s %12s %s\n", $6,$10,$13,myfilename}'

Além disso, agora que os espaços são sublinhados, posso classificar o resultado no nome do arquivo sem reorganizar as colunas para a classificação.

| sort -k 4
    
por 22.04.2015 / 20:15

Tags