Search code examples
linuxbashsh

How can I list an output of files and let the user select them


I have to do a bash script that shows disk usage and free space and if a certain point is set as an argument of that script, allow user to select files that are greater than 10MB and delete them or pack and move them somewhere else and check if that point is satisfied and if not repeat that action. So far for listing files from all of /home/$USER that are over 10MB i got this command line:

find . -size +10M -exec ls -Rla --block-size=M -I ".*" {} \+ | sort -n | awk '{print "PERM: " $1 " SIZE: " $5 " PATH: " $8}'

I got some serious issues with it like awk is not sorting out files with spaces in their paths and if files that doesn't have a hour value are not shown neither because columns doesn't match. I don't know why -I ".*" statement is not working too.

So my question "Is it possible to do that in one script - like generating a list of files over 10MB and letting user to chose from them?"


Solution

  • Paths are allowed to have any characters except zero byte. The only possible way to work safely with any files is to use zero separated streams. Note that you have to have GNU tools then as they support various -z/-0 options, or use a different programming language. A common trick is to put before the filename stuff that will have known format, and then put the filename. That way you can extract them with like a regex (or with cut -d' ' -f2-).

    find . -type f -size +10M -printf '%s %p\0' |
    sort -z -n -k1 |
    awk -v RS="\0" '
    {
         # remove everything after the first space
         size = $0; gsub(/ .*$/, "", size)
         # remove everythign before the first space
         file = $0; gsub(/^[^ ]* /, "", file)
         print "SIZE: " size " PATH: " file
    }'