Files by size

I am new to Unix and need help. I have several files of different sizes Example: 1 GB , 2GB , 500 mb ,200mb and even small sizes. What I want is I want to pick files and sum of the combined file size should be less than 3 Gb and move them to a different directory. when I do ls -ltr I want to pcik files of size 3 GB (files sizes combined it could be 2 files or 3 files or 30 files but should be less than 3 GB ). every time the script should pick up files less than 3 GB . For any reason there are only 5 files and the total size is less than 3 Gb then all those files should be picked and moved as well. We are in AIX unix Please let me know if you need more information. Thank you in advance for your help.

By specifying ls -ltr , I assume that you are trying to move the oldest file each time you invoke this script. Is the intent to move only the oldest files in that directory and quit selecting files when the next oldest file would create a combined size >= 3 GB? Or is the intent to move the oldest file and select more files until you get as close as possible to 3GB even if some of the selected files are not the oldest files in the directory?

By 3 GB do you mean 3 * 1000 * 1000 * 1000, or do you mean 3 * 1024 * 1024 * 1024?

Yes the intent is to move the oldest file and select more files until you get as close as possible to 3GB even if some of the selected files are not the oldest files in the directory and just think there are 20 files and total combined size is 2 GB then we want all the files to be moved as well.

By 3 GB I mean 3 * 1000 * 1000 * 1000 . Thank you for your help Don Appreciate it.

One could try something like:

#!/bin/ksh
destination=/destination/directory
left=3000000000
source=/source/directory

if ! cd "$source"
then	exit 1
fi
ls -ltr | grep '^-' | while read _ _ _ _ size _ _ _ name
do	if [ $size -lt $left ]
	then	left=$((left - size))
		printf 'Moving "%s", size: %d, looking for %d more.\n' \
		    "$name" $size $left
		echo mv "$name" "$destination"
	else	printf 'File "%s", size: %d, too big to move this time.\n' \
		    "$name" $size
	fi
done

If you change the values assigned to destination and source to pathnames to the destination and source directories you want to use and run the code as it is above, it will tell you which files it would select from the directory named by source to be moved to the directory named by destination , show you the sizes of the files being moved, and show you the mv commands that would be issued to move those files (without actually moving anything). If you try that and it looks like it is doing what you want, you can remove all of the code shown in red and the script will just silently move the oldest files it can find as long as the total size of the moved files is less than 3000000000 bytes.

1 Like

Thank you Don for your Quick reply , it works as expected . I appreciate it so much.

This script (we call ours lz) has an optional "-r" first parameter for descending sizes and/or the star name(s) you would put after an ls command.

rev=""
if [ $# -gt 0 ]
  then
  if [ $1 = '-r' ]
  then
    rev="r"
    shift
  fi
fi
ls -l $* |grep -v "total " |sort +4n$rev -5 +8 |more -e

Same sized files are listed alphabetically.