2015-11-01 3 views
1
count=0;  #count for counting 
IFS=' 
' 
for x in `ls -l $input`;  #for loop using ls command 
do 
a=$(ls -ls | awk '{print $6}') #print[6] is sizes of file 
echo $a 

b=`echo $a | awk '{split($0,numbers," "); print numbers[1]}'` 
echo $b  
if [ $b -eq 0 ]   # b is only size of a file 
then 
count=`expr $count + 1` #if b is zero , the count will increase one by one 
fi 
echo $count 
done 

Я хочу найти 0 размер файлов. Я делаю это, используя команду find. Во-вторых, я хочу, чтобы подсчитать количество файлов с 0, используя команду ls и awk. Но это не настоящий код. Какая у меня ошибка?ls команда и размер файлов в сценарии оболочки

+4

[Не анализировать выходные данные 'ls'] (http://mywiki.wooledge.org/ParsingLs). –

+0

Я не знаю другого использования. Ls неправда? @gniourf_gniourf – esrtr

+1

@lurker Даже это не рекомендуется, потому что количество строк вывода - это не количество файлов, если имена файлов содержат новую строку. – chepner

ответ

1

Ваша основная ошибка: вы parsing ls!

Если вы хотите, чтобы найти (обычные файлы), которые являются пустыми, и если у вас есть версия find, которая поддерживает -empty предикат, использовать его:

find . -type f -empty 

Обратите внимание, что это будет рекурсию во вложенных папках тоже; если вы не хотите этого, используйте:

find . -maxdepth 1 -type f -empty 

(при условии, что ваш find также поддерживает -maxdepth).

Если вы хотите, чтобы подсчитать, сколько пустой (регулярные) файлы у вас есть:

find . -maxdepth 1 -type f -empty -printf x | wc -m 

и если вы хотите, чтобы выполнять обе операции одновременно, то есть напечатать имя или сохранить их в массив для дальнейшего использования, и сосчитать их:

empty_files=() 
while IFS= read -r -d '' f; do 
    empty_files+=("$f") 
done < <(find . -maxdepth 1 -type f -empty -print0) 
printf 'There are %d empty files:\n' "${#empty_files[@]}" 
printf ' %s\n' "${empty_files[@]}" 

с Bash≥4.4, вы могли бы использовать mapfile вместо while - петли read:

mapfile -t -d '' empty_files < <(find . -maxdepth 1 -type f -empty -print0) 
printf 'There are %d empty files:\n' "${#empty_files[@]}" 
printf ' %s\n' "${empty_files[@]}" 

Для POSIX-совместимый способ, использовать test с -s вариант:

find . -type f \! -exec test -s {} \; -print 

и если вы не хотите рекурсию подкаталогов, вам придется -prune им:

find . \! -name . -prune -type f \! -exec test -s {} \; -print 

и если вы хотите, чтобы сосчитать их:

find . \! -name . -prune -type f \! -exec test -s {} \; -exec printf x | wc -m 

и здесь, если вы хотите выполнить обе операции (считать их и сохранить их в массиве для дальнейшего использования), используйте предыдущую while - read цикл (или mapfile, если вы живете в будущем) с этим find:

find . \! -name . -prune -type f \! -exec test -s {} \; -exec printf '%s\0' {} \; 

Также см chepner's answer для чистого раствора оболочки (нуждается в незначительной настройке, чтобы быть POSIX-совместимой).


Относительно Ваш комментарий

Я хочу, чтобы считать и удалить [пустые файлы]. Как я могу это сделать одновременно?

Если у вас есть GNU find (или find, который поддерживает все лакомства):

find . -maxdepth 1 -type f -empty -printf x -delete | wc -m 

если нет,

find . \! -name . -prune -type f \! -exec test -s {} \; -printf x -exec rm {} \; | wc -m 

Убедитесь, что -delete (или -exec rm {} \;) предикат в конце! не меняйте порядок предикатов!

+0

Я хочу считать и удалять 0 байтов. Как я могу это сделать одновременно? – esrtr

+0

@esrtr см. Нижнюю часть сообщения. –

2

Тест -s имеет значение true, если файл имеет ненулевой размер. Если этот тест завершился неудачно для файла, увеличьте количество ваших пустых файлов.

empty_files=0 
for f in "$input"/*; do 
    [ -s "$f" ] || : $((empty_files++)) 
done