43

I would like to create symbolic links (ln -s) to all files (or a class of files, e.g. ending with .bar) in a certain directory. Say I'm in the cwd and type ls ../source/*.bar gives me

foo.bar
baz.bar

how can I pass the parameter list to ln -s that it finally resolves to

ln -s ../source/foo.bar
ln -s ../source/baz.bar

Of course I know I can write a bash script, but there should be something simpler involving xargs or so since it seems to be a common task - at least for me.

75

ln does take multiple arguments, but don't forget to give a target directory in that case.

So, in your example . is the target directory, so it should be as easy as

ln -s ../source/*.bar .

From man ln; the command above uses the 3rd form:

ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
ln [OPTION]... TARGET                  (2nd form)
ln [OPTION]... TARGET... DIRECTORY     (3rd form)
ln [OPTION]... -t DIRECTORY TARGET...  (4th form)
  • In the 1st form, create a link to TARGET with the name LINK_NAME.
  • In the 2nd form, create a link to TARGET in the current directory.
  • In the 3rd and 4th forms, create links to each TARGET in DIRECTORY.
  • 5
    You just saved me 5 solid minutes of my life, worth enough to spend one of them leaving a comment. :-) – moodboom Mar 24 '15 at 20:47
  • This doesn't work if there are no files *.bar. It will create a link with the name "*.bar", which is not what you want. – Nimrod May 9 '17 at 16:28
  • 1
    @Nimrod: That's true, but you can tell bash that you want it to report an error instead via shopt -s failglob; see e.g. unix.stackexchange.com/a/216227/33390 (The equivalent in zsh is setopt nomatch, which is turned on by default) – mpy May 9 '17 at 17:25
  • :clapping: nice! – Chris Schmitz Mar 5 at 17:28
3

Use find

certainDir="/path/to/dir"
find -name "*.bar" -exec ln -s {} "$certainDir" \;

Also, remember to use full paths (where possible) with symlinks.

  • 2
    Thanks, but isn't it find $certainDir -name "*.bar" -exec ln -s {} \;? And why should I use full paths? I find it quite convenient to know that links stay intact when I move a directory tree around wihch has some internal links. – dastrobu Aug 19 '13 at 8:56
  • That depends where you want to symlink the directories. And I can't remember why full paths are a good idea, it might have been for hard links but I burned that into my mind for a reason. Hmmm. – justbrowsing Aug 19 '13 at 8:59
  • Thanks, your answer is great. Since mpy's answer is the simpler solution to the question, the point goes to him/her. I would accept both answers, if I could. – dastrobu Aug 19 '13 at 9:07
3

You can try recursively either with using globstar (bash/zsh set by: shopt -s globstar):

ls -vs ../**/*.bar .

Note: Added -v for verbose.

Or if the list is too long, using find utility:

find .. -name \*.bar -exec ln -vs "{}" dest/ ';'

This will create links in dest/, or change it to . for current folder.

  • The second one is the correct answer. – Nimrod May 9 '17 at 16:35
0

cp with -s option can create a soft links (or -l for hard links).

From current directory can by used like this:

$ cp -s ../path/with/scripts/* .

In your case it will be like this:

$ cp -s ../source/*.bar .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.