0

Any advise on how to do delete all files and only keep the latest file in each sub-directories, starting from a specific directory? This is what I have tried:

#!/bin/bash

find /home/ftp/ -type f | while IFS= read -r line
do
  find "$line" -type f | head -n -1 | while read file
  do
    #rm -f "$file"
    echo "$file"
  done
done

I have 2 sub-directories in /home/ftp/upload and /home/ftp/download. Both sub-directories have 2 files in each of the sub-directories.

When tested the script above, there is no file name echo out.

4
  • 3
    try something yourself first... if you are new to command line and shell scripting, have a look at stackoverflow.com/documentation/bash/topics and mywiki.wooledge.org/BashGuide .. or search online, lots of them are there Commented Jul 25, 2016 at 8:37
  • HINT: find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head -n1 will list the latest file name. Use this logic to develop your script. If you fails at some point, do ask. Commented Jul 25, 2016 at 8:45
  • Edit that exact command into your question and specify what result you are getting and what result you expect. Commented Jul 25, 2016 at 8:51
  • Your first find should be -type d to select the directories. Note, though, that the second find doesn't order the results so you may end up keeping files at random, rather than "latest". Commented Jul 25, 2016 at 11:40

1 Answer 1

1

With zsh, from the current directory:

for dir (**/*(N/)) {
  files=($dir/*(N.om))
  (($#files > 1)) && echo rm -f -- $files[2,-1]
}

If you want hidden directories and files considered, add the D glob qualifier.

That only considers regular files. If you want other types of files like devices, sockets, named pipes, or if you want to follow symlinks, it can be adapted with more glob qualifiers.

Remove the echo to actually do the task.

With recent GNU tools and a POSIX shell:

(export LC_ALL=C
find . -type f -printf '%T@\t%p\0' |
  sort -rzn |
  cut -zf2- |
  gawk -v RS='\0' -v ORS='\0' '
    match($0,/.*\//) && n[substr($0,1,RLENGTH-1)]++' |
  xargs -r0 echo rm -f
)

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.