Ubuntu – Move only the last 8 files in a directory to another directory

command linedirectoryfilesmvtail

I'm trying to move the last 8 files from the Documents directory to another directory, but I don't want to move them one-by-one to that specific directory. Is it possible to move them with a substitute of the tail command, but for directories instead of files? I mean I'd like to do so with something like tail -8 ./Documents | mv ./Anotherdirectory or with mv tail -8 ./Documents ./Anotherdirectory.

In fact, I'm looking for a clever way I could move the last 8 files (as listed in ls) quickly (without typing out each name) to the other directory. Any suggestions?

Best Answer

You can use for, which loops over the files in an ordered way, and allows us to avoid parsing the output of find or ls, to avoid issues with spaces and other special characters in filenames. Many thanks to @muru for improving this :)

i=0; j=$(stat ~/Documents/* --printf "%i\n" | wc -l); for k in ~/Documents/*; do if (( (j - ++i) < 8 )); then echo mv -v "$k" ~/AnotherDirectory; fi; done 

Test it first with echo, then remove echo to actually move the files.

As a script:

#!/bin/bash
i=0
j=$(stat ~/Documents/* --printf "%i\n" | wc -l )
for k in ~/Documents/*; do
  if (( (j - ++i) < 8 )); then
    echo mv -v -- "$k" ~/AnotherDirectory
  fi
done

again, remove echo after testing to move the files for real

Explanation

  • i=0 telling the shell to start iterating at 0
  • j=$(stat ~/Documents/* --printf "%i\n" | wc -l ) this is setting the variable j to an integer equal to the total number of files in the directory. Thanks to Serg's answer to my own question on how to count files reliably no matter what characters their names contain
  • do if (( (j - ++i) < 8 )) for each iteration of the loop, test whether the outcome of j minus the number of times the loop has been run is less than 8 and if it is then
  • mv -v -- "$k" ~/AnotherDirectory move the file to the new directory