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/{} \;
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityYou only have to change one character in your command:
find * -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;
# ^
!
, (
or )
or anything starting with a -
in the current directory. It will also skip the hidden files and dirs in the current directory.
Apr 12, 2013 at 13:07
.h
on my systems (ubuntu Linux).
find
stuff in another directory (eg. find src/ -type l
), is there a way to exclude src/
from the results?
Apr 22, 2021 at 11:38
cd src; find * -type l
in that case.
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
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.
$PWD
off the destination of the ln
command.
Apr 12, 2013 at 11:44
find . -type l -name '*.h' -print0 | cut -z -c3- \
| xargs -0 -I '{}' ln -s '/sourcedir/{}' '/destinationdir/{}'
-print0
print the full file name on the standard output, followed by a null
character.man cut
- remove sections from each line of files
-z
line delimiter is NUL
, not newline.-c
select only these characters.N-
from N'th byte, character or field, counted from 1, to end of line.man xargs
- build and execute command lines from standard input.
xargs [options] [command [initial-arguments]]
-0
Input items are terminated by a null
character instead of by whitespace,
and the quotes and backslash are not special (every character is taken
literally).-I replace-str
Replace occurrences of replace-str
in the initial-arguments
with
names read from standard input. Also, unquoted blanks do not terminate
input items; instead the separator is the newline character.
Implies -L 1
.-L max-lines
Use at most max-lines
nonblank input lines per command line.
find
supporting the-printf
option?find . -type l -name '*.h' -printf 'ln -s /sourcedir/%f /destinationdir/%f\n'
's output. If you like it, pipe it tosh
. Of course, special characters in the file names will be a problem.find sourcedir -type l -name '*.h' -exec ln -s {} /destinationdir/{} \;
... You would run the find command from the parent of /sourcedir, which is the root. On second thought that won't work because it will try to create a link called /destinationdir/sourcedir/file.h