Darotudeen
Darotudeen

Reputation: 2518

How to use stat on a file within a loop in bash programming

I am trying to take a folder name through the prompt and perform task like get file size or read lines in files in a for loop but I keep getting error on the functions applied in the loop.

I have tried to use stat and cat but got the same error cat/stat: test.js: No such file or directory

read -p "Please provide the folder name; " FOLDERNAME
COUNT=0
SIZE=0
EACH=0
if [ -d "$FOLDERNAME" ]
then
    FILES=$(ls $FOLDERNAME )
    echo "checking $FOLDERNAME folder "
    for FILE in $FILES
    do
         echo "$FILE"
         echo $(cat $FILE)
        #  $(stat -c%s $FILE)
        #  echo $EACH
        #  (($SIZE=$SIZE+$EACH))
        ((COUNT++))
    done
    echo "You have $COUNT files in the $FOLDERNAME"
    # echo "$(stat $FOLDERNAME | grep Size  | tail -1  | cut -f1)"
    echo $(stat -c%s "$FOLDERNAME")
    echo "$SIZE"
else
    echo "$FOLDERNAME is does not exist"

fi

The program is runs as thus

Hello World!
Please provide the folder name; test
checking test folder 
test.c
cat: test.c: No such file or directory

test.css
cat: test.css: No such file or directory

test.js
cat: test.js: No such file or directory

test1.txt
cat: test1.txt: No such file or directory

test2.txt
cat: test2.txt: No such file or directory

test3.txt
cat: test3.txt: No such file or directory

You have 6 files in the test
4096
0

Upvotes: 1

Views: 1117

Answers (1)

John Kugelman
John Kugelman

Reputation: 361605

Avoid parsing the output of ls. Instead, you can get file names with a simple * glob and store them in an array variable:

FILES=("$FOLDERNAME"/*)
for FILE in "${FILES[@]}"; do
     echo "$FILE"
     cat "$FILE"
done
echo "You have ${#FILES[@]} files in the $FOLDERNAME"

An array is nice because it'll preserve any file names that contain spaces or other special characters. It also gives you an easy to way to count the files with ${#FILES[@}} so you don't need the $COUNT variable.

Note that echo $(<command>) is a convoluted way of writing simply <command>. If you're going to capture a command's output just to echo that output, cut out the middle man and simply run the command directly.

(If you're wondering why your script doesn't work, it's because ls doesn't print $FOLDERNAME in front of each file. It simply prints the file names without their parent directory. The glob version above doesn't have that problem.)

Upvotes: 3

Related Questions