jon
jon

Reputation: 6246

linux create symlinks based on most recently modified files

I want to recursively search a directory tree and get the 10 most recently modified files. For each one of these files, i want to create a symlink in my /home/mostrecent/ directory.

I know i could solve this with a scripting language, but I'm a bit miffed that I can't do it with a linux command!

So far i have this:

find /home/myfiles -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort | tail -n 10 | cut -c 32-

How do i create a symlink in /home/mostrecent for each one of these files, without using a scripting language?

Upvotes: 1

Views: 1732

Answers (3)

BBW Before Windows
BBW Before Windows

Reputation: 638

Create symlinks to several file types modified in the last 24 hrs, with the same filenames (but a different path of course)

Thanks to Pax, Jan and Jon, with a little modification...

Make a 'recent' directory

mkdir ~/recent

Create 'getrecentfiles.sh' and add...

#!/usr/bin/bash
find $HOME -mtime 0 -name \*.txt -print -o \
           -mtime 0 -name \*.pdf -print -o \
           -mtime 0 -name \*.extensionname -print -o | while read f; do
        ln -s $f $HOME/recent/
done

filters:

-mtime (n*24hrs) is time since last modified (n=1 shows only files modified bw 24-48hrs ago)

-o is the OR operator for multiple files (default is AND)

Change it to executable, add it to your startup scripts and make a shortcut to ~/recent on your desktop, to have the latest files you want on hand!

Upvotes: 1

jon
jon

Reputation: 6246

I solved this with sed.

All hail sed!

find /home/myfiles/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort | tail -n 10 | cut -c 21- | sed -e "s/^/ln -s \"/" -e "s/$/\"/" -e "s/$/ \"\/home\recent\/\"/" | sh

If i pipe sed to cat instead of sh, this is the output:

ln -s "/home/myfiles/1.simplest" "/home/recent/"
ln -s "/home/myfiles/2.with space" "/home/recent/"
ln -s "/home/myfiles/3.with'apostraphe" "/home/recent/"
ln -s "/home/myfiles/4.with'apostrophe space" "/home/recent/"

Thanks for your help.

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 882028

Actually, bash is a scripting language, more than capable of doing that sort of stuff even from the command line :-)

Assuming that the command you posted works (and it seems to, based on my cursory testing), you can just do:

i=0
for f in $(CMD) ; do
    ln -s $f $HOME/recent$i
    ((i++))
done

Or, as a one-liner:

i=0;for f in $(CMD);do ln -s $f $HOME/recent$i;((i++));done

This will create the files recent0 through recent9 in your home directory, which are symlinks to the most recent files.

Obviously, you should put your actual command where I've put the marker text CMD above. I've used the marker just so it formats nicely here on SO.


As Jan Hudec points out in a comment, that will only work for files without spaces, evil things in my opinion :-)

But, since people seem to use them, you can use the safer:

i=0
CMD | while read f; do
    ln -s $f $HOME/recent$i
    ((i++))
done

And, again, the one-liner version:

i=0;CMD|while read f;do ln -s $f $HOME/recent$i;((i++));done

Upvotes: 2

Related Questions