How to Create Symbolic Links with Wildcards in Linux

cplnsymlink

I have multiple hard drives with the same directory hierarchy, for example:

/media/sda/dir1
/media/sda/dir2
...
/media/sdb/dir1
/media/sdb/dir2

Two hard drives with similar names and similar directory names.
I want to create separate symbolic links to dir1 and dir2 on every hard drive.
The easiest way I have found is to use cp -sR:

cp -sR /media/sd*/dir1 /somedir/dir1
cp -sR /media/sd*/dir2 /somedir/dir2

However, this creates new directories in /somedir which has various side effects, for example, the directory timestamps are useless.

How can I create symbolic links named dir1 and dir2 which link to /media/sd*/dir1 and /media/sd*/dir2? Files are regularly added to the hard drives so I would need to run these commands on a regular basis.

Best Answer

You might want to do that:

for dir in dir1 dir2
do
  [[ ! -d /somedir/$dir ]] && mkdir /somedir/$dir    
  find /media/sd*/$dir -type f -exec bash -c \
    '[[ ! -f /somedir/'$dir'/$(basename $1) ]] && ln -s $1 /somedir/'$dir'/' foo {} \;
done

This create symbolic links in /somedir/dir1/ (resp. dir2) pointing to all files present under /media/sd*/dir1 (resp. dir2). This script doesn't preserve hierarchy that might be present under the source directories.

Edit: Should you want all the links to be placed in a single directory, here is a slightly modified version:

[[ ! -d /somedir/data ]] && mkdir /somedir/data    
find /media/sd*/dir[12] -type f -exec bash -c \
    '[[ ! -f /somedir/data/$(basename $1) ]] && ln -s $1 /somedir/data/' foo {} \;
done
Related Question