Ubuntu – Is it possible to rename files selected by ls

command linefileslsrename

I have some files I downloaded recently and I want to name. It is possible to do something like:

rename 's/ /_/g' $(ls -t | head -n5) 

Actually, I would like to rename last downloaded 5 files.

Any idea?

Best Answer

First, I have to note, parsing ls is generally not recommended. Its output is meant for human consumption, and this solution will fail for some legitimate file names (like those which contain newline characters, for example)

With that said, the simplest solution does seem to be using ls (as find does not offer a sort-by-modification-date option). For this, you can use pipes and the xargs command to execute the final rename.

In short:

ls -1t | head -n5 | xargs -I {} rename 's/ /_/g' {}

This uses your original command almost exactly, but with xargs to do the final completion. xargs will take in a number of newline-separated arguments, and pass them all to a single rename command.

Caveats

This should work - but parsing ls is fragile. This breaks for file names which contain the newline character; using a command that's meant for parsing like find would be much better.

However, I don't know how to sort by last modification date with find. If someone else knows how to do this, you'd probably end up with something like:

find . -mindepth 1 -maxdepth 1 -print0 | sort <???> -Z | head -z -n5 | xargs -0 rename 's/ /_/g'

If <???> were a valid argument, this command chain would tell find to output files in the current directory separated with a NUL character, and then sort, head, and xargs would all accept this as the deliminator rather than a newline - making the whole process much more consistent. Feel free to comment or edit this if you know how to do this, and want to replace the ls answer with this bottom part.