2015-02-25 6 views
1

поэтому я пытаюсь написать программу, которая будет считать файлы, каталоги и исполняемый файл в домашнем каталоге. По какой-то причине он не считывает правильные номера для количества файлов, каталогов или исполняемых файлов. Когда я в командной строке он читаетПодсчет количества файлов, каталогов и исполняемых файлов в домашнем каталоге с использованием сценариев оболочки

ls ~/* | ls -f | wc -l = 31 
ls ~/* | ls -d | wc -l = 1 
ls ~/* | ls -x | wc -l = 5 

Это мой код и выход

files=0 
directories=0 
executables=0 

for i in ~/*;do 
    if [[ -f "$i" ]];then 
     files=$(($files + 1)) 
    elif [[ -d "$i" ]];then 
     directories=$(($directories + 1)) 
    elif [[ -x "$i" ]];then 
     executables=$(($executables + 1)) 
    fi 
done 
echo Files $files, Directories $directories, Executables $executables 

Выход файлов 14, Справочники 2, Executables 0

Почему это случающиеся кого?

ответ

0

Я хотел бы использовать find и трубочного результаты в awk:

find "$HOME" -mindepth 1 -maxdepth 1 -printf "%Y %M\n" \ 
    | awk '/f/{f++}/^f.*x/{x++}/d/{d++}END{printf "Files: %s Directories: %s Executables: %s\n",f,d,x}' 
+0

Посмотрите, как я пытался использовать $ HOME, и он дал мне файлы 0, каталоги 1 и исполняемые файлы 0. И я не знаю почему. –

+0

Эй, я, наверное, понял, что ты неправ. Проверьте мое редактирование, оно работает для вас? – hek2mgl

+0

Эй, поэтому я пытался избежать awk полностью, потому что я не очень хорошо это понимаю, но моя главная цель состояла в том, чтобы выяснить, что не так с моей программой и почему она производит этот вывод. –

2
  • ls -f: перечислит без сортировки. Это подразумевает -a. Итак, вы получите все, включая . и .., файл или каталог. Это совсем не похоже на тест [[ -f $file ]]. Вот почему ответ ls -f | wc -l 31 намного больше, чем 14 из вашего скрипта.
  • ls -d: будет отображать каталог вместо содержимого. Без каких-либо аргументов это логически 1, что соответствует . (он не перечисляет содержание .). Вот почему вы получаете 1.
  • ls -x: перечислять записи по строкам вместо столбцов ... так что это просто не будет считать что-либо значимое.

Ваш скрипт почти нормально ... за исключением того, что из-за ваших if/elif заявлений, последнее испытание не почти никогда не будет проверяться: исполняемые файлы и каталоги будут if «d раньше!

Вы очень вероятно, хотите:

#!/bin/bash 

files=0 
directories=0 
executables=0 

for i in ~/*;do 
    if [[ -f $i ]];then 
     ((++files)) 
     if [[ -x $i ]]; then 
      ((++executables)) 
     fi 
    elif [[ -d $i ]];then 
     ((++directories)) 
    fi 
done 
printf 'Files: %s, among which %d are executable\n' "$file" "$executables" 
printf 'Directories: %s\n' "$directories\n' 
+1

Я только учился в bash в течение нескольких дней, поэтому его довольно новый для меня. И да, это имеет смысл. –

+1

Также проверьте это: http://stackoverflow.com/questions/28767112/read-command-in-bash-script-with-n1-argument/28767209#comment45813372_28767209 ...:) nice +1 – hek2mgl

1

Вы должны проверить сначала каталоги и следующей проверки для исполняемого файла, потому что исполняемый файл также файл, следовательно, ваш сценарий никогда не достигает в этом состоянии:

elif [[ -x "$i" ]];then 

Вот исправленная версия вашего сценария:

for i in ~/*; do 
    if [[ -d "$i" ]];then 
     ((directories++)) 
    elif [[ -x "$i" ]];then 
     ((executables++)) 
    elif [[ -f "$i" ]];then 
     ((files++)) 
    fi 
done 

echo "Files: $files, Directories: $directories, Executables: $executables" 
+0

Ну ладно, что имеет смысл, я не знал, что вы также можете сделать ((каталоги ++)) –

+0

Да, это ярлык 'directories = $ (($ directories + 1))' – anubhava

Смежные вопросы