Home > front end >  bash iterate over a directory sorted by file size
bash iterate over a directory sorted by file size

Time:06-11

As a webmaster, I generate a lot of junk files of code. Periodically I have to purge the unneeded files filtered by extention. Example: "cleaner txt" Easy enough. But I want to sort the files by size and process them for the "for" loop. How can I do that?

cleaner:

#/bin/bash

if [ -z "$1" ]; then
echo "Please supply the filename suffixes to delete.";
exit;
fi;

filter=$1;

for FILE in *.$filter; do clear; 

cat $FILE; printf '\n\n'; rm -i $FILE; done

CodePudding user response:

You can use a mix of find (to print file sizes and names), sort (to sort the output of find) and cut (to remove the sizes). In case you have very unusual file names containing any possible character including newlines, it is safer to separate the files by a character that cannot be part of a name: NUL.

#/bin/bash

if [ -z "$1" ]; then
echo "Please supply the filename suffixes to delete.";
exit;
fi;

filter=$1;

while IFS= read -r -d '' -u 3 FILE; do
  clear
  cat "$FILE"
  printf '\n\n'
  rm -i "$FILE"
done 3< <(find . -mindepth 1 -maxdepth 1 -type f -name "*.$filter" \
  -printf '%s\t%p\0' | sort -zn | cut -zf 2-)

Note that we must use a different file descriptor than stdin (3 in this example) to pass the file names to the loop. Else, if we use stdin, it will also be used to provide the answers to rm -i.

CodePudding user response:

Inspired from this answer, you could use the find command as follows:

find ./ -type f -name "*.yaml" -printf "%s %p\n" | sort -n

find command prints the the size of the files and the path so that the sort command prints the results from the smaller one to the larger.

In case you want to iterate through (let's say) the 5 bigger files you can do something like this using the tail command like this:

for f in $(find ./ -type f -name "*.yaml" -printf "%s %p\n" |
           sort -n | 
           cut -d ' ' -f 2)
do 
    echo "### $f"
done 

CodePudding user response:

If the file names don't contain newlines and spaces

while read filesize filename; do 
  printf "%-25s has size  d\n" "$filename" "$filesize"
done < <(du -bs *."$filter"|sort -n)

while read filename; do
  echo "$filename"
done < <(du -bs *."$filter"|sort -n|awk '{$0=$2}1')
  •  Tags:  
  • bash
  • Related