Is it possible to move last modified files using ls, tail and mv?

5,752

Solution 1

The command you are looking for is xargs, as tail doesn't have a native ability to execute a program.

The full command would be:

ls -tr | tail -n 3 | xargs -I{} mv {} /home/user/Desktop

Breaking it down:

  • ls -tr lists files sorted by modification date/time (-t). The most recent are first, by default; it's reversed (most recently modified files last) if you add -r.
  • tail -n 3 filters it down to the last three entries.
  • xargs -I{} mv {} /home/user/Desktop runs mv {} /home/user/Desktop for each line received from tail. Note that the {} is replaced by the output from tail.

Note that you may need to escape the curly brackets in the call to xargs.

xargs -I\{\} mv \{\} /home/user/Desktop

Solution 2

Depending on the names on the files, a solution relying on the output of ls might be problematic. Using zsh, one could rely on globbing flags to get the job done:

mv *(.om[1,3]) ${somewhere}

The ‘magic’ is between the two parentheses after the *:

  • . only selects plain files;
  • om sorts the results of the glob by mtime;
  • [1,3] selects the first three results

I’m aware that the question specifically asks for a bash solution, so strictly speaking this answer won’t qualify. I’m posting it nonetheless for others who might have similar tasks and can use other shells.

Share:
5,752

Related videos on Youtube

Robert Smith
Author by

Robert Smith

Updated on September 18, 2022

Comments

  • Robert Smith
    Robert Smith almost 2 years

    I want to move the last 3 modified files from a directory using bash commands. However, I noticed that I can use find in the following way:

    find . -type f -mtime -0.5 -print -exec mv {} /home/user/Desktop \;
    

    But I haven't figured out how to do the same with ls -tr | tail -n 3. For example, this doesn't work:

    ls -tr | tail -n 3 -exec mv {} /home/user/Desktop             
    tail: invalid option -- 'e'
    

    The only reason I'd prefer to use the second option is in order to specify a number of files instead of an approximate time. Is it possible to make it work with ls and tail

    Thanks!

  • Robert Smith
    Robert Smith almost 10 years
    Thanks. Actually, your suggestion was my first option but I wasn't too pleased with it because I didn't understand why I need to use the curly brackets next to -I. Do you know why?
  • neersighted
    neersighted almost 10 years
    You need to specify a placeholder. By default, xargs appends all arguments to the command. You need to insert each argument into a seperate command, in the middle. This requires the placeholder.
  • pabouk - Ukraine stay strong
    pabouk - Ukraine stay strong over 9 years
    To your suggested edit of the other answer superuser.com/review/suggested-edits/301337 ------ Yes, ls by default arranges the files in columns but only if its output goes to a terminal. Compare: ls and ls | cat.