1

I have to write a script that will count the no of files in a directory in every 1sec.

for item in /d:/new_dir/*
do
if [ -f $item ]
then
     FILECOUNT=$[$FILECOUNT+1]
fi
done
     echo -e "No of files are $FILECOUNT\r\c";
FILECOUNT=0
sleep 1s
done

But I want to see which files were added or deleted between two iterations. Please tell me what modification do I need to change in the above code.

Naren
  • 2,231
  • 1
  • 25
  • 45
abc
  • 37
  • 1
  • 10
  • Is the language specified? `sh`, `bash`, `perl`? – SzG Sep 19 '13 at 06:20
  • [Same](http://stackoverflow.com/questions/18820409/shell-script-to-count-the-no-of-incoming-files-in-a-directory-in-10sec) question [rephrased](http://stackoverflow.com/questions/18815423/shell-script-to-count-the-number-of-files-coming-in-a-directory) three ways? – beroe Sep 24 '13 at 21:07

3 Answers3

1

I'm using ls to list the directory, wc to count, diff to show added/deleted files, sed for filtering out dirs/symlinks and diff metadata, and bash process substitution <() to trick diff into thinking it's comparing 2 files while comparing just 2 variables.

#!/bin/bash
dir=$1
old=`ls -1F $dir | sed '/[\/@]$/d'`
while true; do
  new=`ls -1F $dir | sed '/[\/@]$/d'`
  echo "$new" | wc -l | sed 's/^/No of files is /'
  diff -u <(echo "$old") <(echo "$new") | sed -r '/^((\+\+)|(--)|(@@)| )/d'
  old=$new
  sleep 1
done

Added files will appear like +foo, deleted ones like -foo.

If you're on a Mac or other non-GNU Unices, the diff metadata filter looks like this:

sed '/^\(\(++\)|\(--\)|\(@@\)| \)$/d'

Ugly, huh?

SzG
  • 12,333
  • 4
  • 28
  • 41
  • I didn't know about `<()`. Learn something new every day. – slebetman Sep 19 '13 at 07:26
  • I learned it today too. Googled "diff 2 bash variables" and boy, did I find a stackoverflow page about <()! :-) – SzG Sep 19 '13 at 07:48
  • Why use `diff` and a trick instead of subtraction though? ;^) – beroe Sep 19 '13 at 08:13
  • @beroe: Because you can't subtract two strings? Note that the diff is used to print out a list of added files (with the symbol "+" in front of the file name) and deleted files (with the symbol "-" in front of the file name). The list of files are strings generated by `ls` and the 'trick' is to use diff with strings instead of files. – slebetman Sep 19 '13 at 08:17
  • Apparently I misunderstood the OP, and thought they wanted to see how many files were different. No wonder the other solutions were fancier... – beroe Sep 19 '13 at 08:21
0

How long do you want to do this for? This simple code below will monitor for 60 seconds. To go for infinity, change the for loop to while true; do (then the timer won't increment so remove refs to I) Mind the spaces!

It is faster to get the number of files with ls than in a loop:

NUMFILES=$(ls | wc -l)
echo "T : NUM : DIFF"
for I in {1..60}; do 
   sleep 1
   NEWNUM=$(ls | wc -l)
   echo $I : $NUMFILES : $[$NEWNUM-$NUMFILES]
   NUMFILES=$NEWNUM
done
beroe
  • 11,784
  • 5
  • 34
  • 79
0

This simple script should work for you using internal bash arrays:

a1=( * )
while :; do
   echo "Num of files at present => " ${#a1[@]}
   if [[ $a2 && ${#a1[@]} != ${#a2[@]} ]]; then
      [[ ${#a2[@]} > ${#a1[@]} ]] && echo "new files added =>" && \
                      grep -v -f <(printf "%s\n" "${a1[@]}") <(printf "%s\n" "${a2[@]}")
      [[ ${#a1[@]} > ${#a2[@]} ]] && echo "existing files deleted =>" && \
                      grep -v -f <(printf "%s\n" "${a2[@]}") <(printf "%s\n" "${a1[@]}")
      a1=( * )
   fi
   sleep 5
   a2=( * )
done
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Please explain me the meaning of $, @, # and a1[@] in shell script – abc Sep 25 '13 at 05:59
  • @ArchnaSharma: I can answer any specific question about script Here I'm using bash arrays. Please read a simple tutorial on bash arrays and then let me know your questions. You can read: http://www.thegeekstuff.com/2010/06/bash-array-tutorial/ – anubhava Sep 25 '13 at 07:11