how to remove recursilvely from a directory

I can remove blank lines at end of file using following code

for files in `ls * 2>/dev/null`
do
sed -e :a -e '/^\n*$/N;/\n$/ba' $files > newfile
mv newfile $files
done

How can I change above code, so that it recursively executes that code for all files under a directory?

Use find with option '-type f' so it only returns files relative to the starting point.

for files in `find . -type f 2>/dev/null`
do
    sed -e :a -e '/^\n*$/N;/\n$/ba' $files > newfile
    mv newfile $files
done

I also want to modify this code so that it executes mv command only if there is a blank line at end of file ie otherwise file time stamp remains untouched, is it possible?

I don't believe you can do that with mv. You may have to settle for a copy and remove the old one.

cp -p

The above 'preserves' (hence the 'p') attributes, including the timestamp.

Put this in the for statement replacing the 'mv' statement.

if (( $(wc -l newfile) < $(wc -l $files) ))
then
 mv newfile $files
fi

If blank lines were removed from $files, then newfiles should have a smaller line count, since blank lines still count as lines. Then your time stamp changes only if blanks were removed. If the file was copies over in full, then newfile wont be less than $files and the 'mv' wont happen.

Above code gives me syntax error

+ find . -type f
+ sed -e :a -e /^\n*$/N;/\n$/ba ./Makefile
+ wc -l newfile
+ wc -l ./Makefile
+ let 9 newfile < 9 ./Makefile
let: r 11: syntax error in arithmetic expression " 9 newfile" near n

Sorry, change the if line to :

if (( $(cat newfile | wc -l) < $(cat $files | wc -l) ))
then 
  mv newfile $files
fi

In my haste to avoid using 'cat' unnecessarily I forgot that the file name would be part of the output of the 'wc' command when specified as an argument.