1

I'm trying to create a script to count the number of hidden and non-hidden files in a folder where the script is run. However, I run into an issue where I cannot increment variables.

#!/bin/bash

#A simple script to count the number of hidden and non-hidden files in the folder this script is run in

#Variables to store the number of hidden and non-hidden files and folders
#Variables with a 'h' at the end represent hidden items

files=0
fileh=0

#List all files and folders
#Use grep to folder entries beginning with '-', which are files
#Return the 9th word in the string which is the filename
#Read the filename into the variable 'fls'
ls -al | grep ^- | awk '{print $9}' | while read fls

#If the filename begins, with a dot, it is a hidden file
do
    if [[ $fls == .* ]]
    then
        #Therefore increment the number of hidden files by one
        let fileh++
    else
        #Else, increment the number if non-hidden files by one
        let files++
    fi
done

#Print out the two numbers
echo $files 'non-hidden files'
echo $fileh 'hidden files'

#When I run this script, the output is always zero for both variables
#I don't know why this doesn't work?!

The output of this script is as follows:

jai@L502X~$ ./script.sh 
0 non-hidden files
0 hidden files
3
  • quote your increments like let "fileh++" Commented Dec 28, 2014 at 15:26
  • It did not make any difference. Commented Dec 28, 2014 at 15:31
  • I feel like there is probably an easier way: Commented Dec 28, 2014 at 15:35

4 Answers 4

3

If you want to increment a variable using let, you have to quote your expression, like in

let "i++"

However, I personally prefer to use the double-parentheses syntax, which is

((i++))
# or, if you want a pre-fixed increment
((++i))

Plus, you can use a way shorter syntax for your if statement, using && and ||:

[[ $fls == .* ]] && ((++fileh)) || ((++files))
Sign up to request clarification or add additional context in comments.

Comments

1

What happens on the right hand side of a | happens in a subshell. Changes to variables in a subshell don't propagate back to the parent shell.

Common workaround: don't use a pipe, use Process substitution:

while read fls ; do
   ...
done < <(ls -al | grep ^- | awk '{print $9}')

1 Comment

Thanks, you solution works! I do understand the explanation that you gave, however, I don't understand the syntax used.
0

Not the answer to the "increment" question, but a much easier script to do what you're trying to do:

files=`find . -type f`
echo "non-hidden files " `echo "$files" | egrep -v "[/]\.[^/]+$" | wc -l`
echo "hidden files " `echo "$files" | egrep "[/]\.[^/]+$" | wc -l`

1 Comment

Thanks for the suggestion but I'm doing a challenge where I can't use the commands 'find' 'du' 'locate' or any recursive function.
0

Quote the variable increment

let "fileh++"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.