Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to use find to create a bunch of symlinks but using the result with {} includes ./ before each filename. How can I avoid that?

find . -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;
share|improve this question
    
Is your find supporting the -printf option? –  manatwork Apr 12 '13 at 11:35
    
yes i think it does –  Mark Robinson Apr 12 '13 at 11:38
    
See the find . -type l -name '*.h' -printf 'ln -s /sourcedir/%f /destinationdir/%f\n''s output. If you like it, pipe it to sh. Of course, special characters in the file names will be a problem. –  manatwork Apr 12 '13 at 11:41
    
@manatwork I think you have the best answer there. If you post it as an answer I'll mark it as accepted –  Mark Robinson Apr 12 '13 at 11:56
    
@manatwork, ITYW %P instead of %f here. –  Stephane Chazelas Apr 12 '13 at 12:16
show 1 more comment

3 Answers

Use the standard syntax, like:

S=/sourcedir D=/destdir find . -type l -name '*.h' -exec sh -c '
  for i do
    ln -s -- "$S${i#.}" "$D/$i"
  done' sh {} +

If you want to use GNUisms, you could do:

find . -type l -name '*.h' -printf '/sourcedir/%P\0/destdir/%P\0' |
  xargs -r0n2 ln -s

Or if /sourcedir is the current directory:

find "$PWD" -type l -name '*.h' -printf '%p\0/destdir/%P\0' |
  xargs -r0n2 ln -s
share|improve this answer
add comment

You only have to change one character in your command:

find * -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;
#    ^
share|improve this answer
1  
Good point, but it should be noted though that it would fail if any file is named !, ( or ) or anything starting with a - in the current directory. It will also skip the hidden files and dirs in the current directory. –  Stephane Chazelas Apr 12 '13 at 13:07
    
@StephaneChazelas You are right. I had thought about the hidden files and dirs myself but found only one such file in the 75K .h on my systems (ubuntu Linux). –  Anthon Apr 12 '13 at 13:17
add comment

find will print names relative to the paths you provide as arguments. In this case, the path is ., so all the names will begin with ./. To get absolute paths, you need to provide an absolute path as input:

find "$PWD" -type l -name '*.h'

This command uses the $PWD environment variable, which contains the absolute path of the current working directory, so it should preserve the meaning of your original command.

share|improve this answer
1  
He would then need to strip that $PWD off the destination of the ln command. –  Stephane Chazelas Apr 12 '13 at 11:44
    
good point. Also I think I was answering a question he didn't ask. :( –  bonsaiviking Apr 12 '13 at 11:45
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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