so I am trying to write a program that will count the files, directories, and executable in the home directory. For some reason it doesn't read the right numbers for how many files there are, directories, or executables. When I am in the command line it reads
ls ~/* | ls -f | wc -l = 31
ls ~/* | ls -d | wc -l = 1
ls ~/* | ls -x | wc -l = 5
This is my code and output
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
Output is Files 14, Directories 2, Executables 0
Why is that happening anyone?
ls -f
: will list without sorting. This implies -a
. So, you'll get everything, including .
and ..
, file or directory. It's not at all like the test [[ -f $file ]]
. That's why ls -f | wc -l
ls -f | wc -l
's answer 31 is a lot larger than the 14 from your script. ls -d
: will list directory instead of content. Without any argument, this is, logically, 1, that corresponds to .
(it doesn't list the content of .
). That's why you obtain 1. ls -x
: list entries by lines instead of columns... so this is just not going to count anything relevant whatsoever. Your script is nearly fine… except that because of your if/elif
statements, the last test is nearly never going to be checked: executable files and directories will be if
'd before!
You very likely want:
#!/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'
You need to check for directories first and next check for executable because an executable file is also a file hence your script never reaches inside this condition:
elif [[ -x "$i" ]];then
Here is the corrected version of your script:
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"
I would use find
and pipe the results to 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}'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.