Reputation: 60
I have used this code
#!/bin/bash
ls -l
echo -n "Number of simple files : "
ls -l | egrep '^-' | wc -l
echo -n "Number of directories : "
ls -l | egrep '^d' | wc -l
echo -n "Number of hidden files : "
ls -la | egrep '^.*\.$' | wc -l
echo -n "Number of hidden directories : "
ls -la | egrep '^d.*\.$' | wc -l
echo " End"
While I can understand how the first two egrep work I can't figure out how the last
two work. More specific what does this mean '^.*\.$'
?
I want a file that starts with . (hidden file) and then how I should shape my regular expression?
Upvotes: 0
Views: 2798
Reputation: 295698
You shouldn't be using grep
(or ls
) for this task at all. See http://mywiki.wooledge.org/ParsingLs for an in-depth discussion of how ls
should only ever be used for interactive display to humans.
all_files=( * ) # includes directories
directories=( */ ) # directories only
hidden_files=( .* ) # includes directories
hidden_directories=( .*/ ) # directories only
echo "Number of files: $(( ${#all_files[@]} - ${#all_directories[@]} ))"
echo "Number of directories: ${#directories[@]}"
echo "Number of hidden files: $(( ${#hidden_files[@]} - ${#hidden_directories[@]} ))"
echo "Number of hidden directories: $(( ${#hidden_directories[@]} - 2 ))"
The - 2
in the last calculation is to remove .
and ..
, which will always be present.
Upvotes: 7
Reputation: 42073
The regex doesn't work, because '^.*\.$'
matches the dot at the end of the line. Use these commands instead to count hidden files and directories:
ls -ld .* | egrep '^-' | wc -l
ls -ld .* | egrep '^d' | wc -l
Note that egrep '^d'
matches .
and ..
too, so you need subtract 2 from the result:
ls -ld .* | egrep '^d' | wc -l | awk '{print $1 - 2}'
Alternatives:
ls -ld .* | egrep '^d' | tail -n +3 | wc -l
echo $(($(ls -ld .* | egrep '^d' | wc -l) - 2))
Upvotes: 0
Reputation: 2494
last two work incorrect, but
ls -la | egrep '^.*\.$' | wc -l
ls -la | egrep '^d.*\.$' | wc -l
return 2
ls -la | egrep '^.*\.$'
ls -la | egrep '^d.*\.$'
return
drwxr-xr-x 7 root root 4096 date time .
drwxr-xr-x 31 root root 4096 date time ..
variant:
secret files:
ls -la | grep '^-' |awk '{print $9}' |egrep '^\.[^\.]' |wc -l
secret dirs:
ls -la | grep '^d' |awk '{print $9}' |egrep '^\.[^\.]' |wc -l
Upvotes: 1
Reputation: 3095
Note that your approach of parsing ls
output for this purpose is wrong. See @Dharles Duffy's answer for a better alternative. To answer your question though and explain the regex a little bit:
'^.*\.$'
means
^ // From the beginning of the string
.* // match zero or more of any character
\. // match one literal full-stop
$ // end of the string
I am not sure what you mean with a "secret" file but if you mean a hidden file, i.e. one that begins with .
and then a filename, the way to regex that would be
'^\..*$'
Note that this is not when parsing ls
output and is just for a file or directory name and does not discern between the two.
Upvotes: 1
Reputation: 1740
find $THE_DIRECTORY -maxdepth 1 -type f -name '.*' | wc --lines
Should work, you may want to use -L if you want to find symlinks as well.
Upvotes: 0