Encontre o tamanho do arquivo no unix usando o loop for

1

Estou tentando obter o tamanho de cada arquivo em um diretório usando um loop for, executando o script abaixo

#!/bin/bash
FILE=/home/cloudera/Desktop/new
for    file in $FILE
do
       size='du -b ${file} | cut -f1'
       echo $size
done

Estou recebendo o seguinte erro:

du cannot access /home/cloudera/Desktop/new/a.txt 
du cannot access /home/cloudera/Desktop/new/b.txt 
du cannot access /home/cloudera/Desktop/new/c.txt

onde a.txt, b.txt.c.txt são arquivos dentro do novo diretório.

    
por Raj Abhishek 06.02.2016 / 19:59

3 respostas

3

Em vez de du -b , sugiro que você use find com printf. O principal problema aqui é que du irá recorrer a quaisquer diretórios que encontrar. Seu for loop não consegue ver os arquivos individuais.

find /home/cloudera/Desktop/new -type f -printf "%s %p\n"

Se a sua descoberta não tiver printf, use

-exec stat -c "%s %n" {} \;

Em seguida, envie a saída para um script while:

find <what you do above> | 
while read size ; do 
   # whatever
done

EDIT: Você parece querer encontrar cada arquivo no SOURCEDIR e se o arquivo não existir no DESTDIR ou se o arquivo existir, mas tiver um tamanho de arquivo diferente, copie esse arquivo.

CP="echo /bin/cp -f"
sizeof() { stat -c %s "%1" ; }
cd $SOURCEDIR
find . -type f -print |
  while read name; do
    source_size=$(sizeof $SOURCEDIR/$name)
    if [[ -f $DESTDIR/$name ]]; then
      dest_size=$(sizeof $DESTDIR/$name)
      if [[ $source_size == $dest_size ]]; then
        next # do not copy
      fi
    fi
    $CP $SOURCEDIR/$name $DESTDIR/$name
  done

Mas isso é feio e lento. O cd é necessário para garantir que a saída do find seja um caminho relativo. O uso subseqüente de $SOURCEDIR é redundante e para maior clareza. Eu alias o sizeof para que você possa alterá-lo para du -b ou o que for. Quando a saída parecer correta para você, altere $CP para o comando real (remove echo ).

Aqui está outra maneira de fazer isso. Se você aprender bem, você vai dominar muitas coisas sobre o unix:

CP="echo cp"
{ cd $SOURCEDIR ; find . -type f -printf "%s %p\n" |sort -k 2 ; } >/tmp/source.lst
{ cd $DESTDIR   ; find . -type f -printf "%s %p\n" |sort -k 2 ; } >/tmp/dest.lst
awk 'FNR==NR { f[$2]=$1 } !length(f[$2]) || f[$2]!=$1 { print $2 }' /tmp/dest.lst /tmp/source.lst >/tmp/copythese.lst
cat /tmp/copythese.lst | xargs -n 1 -I ^ $CP $SOURCEDIR/^ $DESTDIR/^ 

Teste. Então, quando a lista parecer correta, altere CP para /bin/cp -f e repita o último comando. Você está fazendo as etapas acima, mas usando listas. O comando awk localiza arquivos na origem que não estão no destino ou têm um tamanho diferente. ($ 1 é tamanho, $ 2 é nome do arquivo, $ f [$ 2] é o tamanho do arquivo em dest ). Em seguida, o xargs executa uma instância de $CP para cada linha em copythese.lst .

    
por 06.02.2016 / 20:19
1
#!/bin/bash
DIR=/home/cloudera/Desktop/new
for    file in $DIR/*
do
       wc -c "$file"
done
    
por 07.02.2016 / 01:39
0

Este script mostra um par <SIZE> <FILE> , em que <SIZE> é seu próprio tamanho em bytes e <FILE> pode ser um arquivo ou um diretório. Se você quiser mostrar apenas arquivos, você deve remover a primeira condição e usar a segunda.

#!/bin/bash
FILE=/home/cloudera/Desktop/new

for i in 'ls $FILE'
do
    if [ -d "$FILE/$i" ]
    then
        msg='ls -ld $FILE/$i'
        size=$(echo $msg | awk -F [\ ] '{print $5}')
        file=$(echo $msg | awk -F [\ ] '{print $9}')
        echo -e "$size \t  $file"

    elif [ -f "$FILE/$i" ]
    then
        msg='ls -l $FILE/$i'
        size=$(echo $msg | awk -F [\ ] '{print $5}')
        file=$(echo $msg | awk -F [\ ] '{print $9}')
        echo -e "$size \t  $file"
    fi
done
    
por 07.02.2016 / 14:02

Tags