I have 2 link directories in ~, ~/PathA (a git directory) and ~/PathB. The ~/PathA is a subdirectory of ~/PathB. Those two are linked to other physical disk. I linked a lot of files to file under ~/PathA/config/ in my ~. I want find out all those link files. show "xxxxx -> yyyyy" format.

This method is often used when we use configuration files from old/other machine.

If I write a script or use pipe, it is easy can do but something ugly. But I want if only use find command I can do it.

Edit: After test many time, I got it. The most important place is -lname and -print.

▶ find ~ -type l ! -path '/home/eexpss/磁盘' ! -path '/home/eexpss/bin' -lname '/home/eexpss/bin/config/*' -printf "%p -> %l\n"
/home/eexpss/.local/share/applications -> /home/eexpss/bin/config/.local+share+applications
/home/eexpss/.local/share/nautilus/scripts -> /home/eexpss/bin/config/.local+share+nautilus+scripts
/home/eexpss/.vimrc -> /home/eexpss/bin/config/fedora.vimrc
/home/eexpss/.proxy.pac -> /home/eexpss/bin/config/.proxy.pac
/home/eexpss/.bash_aliases -> /home/eexpss/bin/config/fedora.bash_aliases
/home/eexpss/.icons -> /home/eexpss/bin/config/.icons/
find: ‘/home/eexpss/磁盘/lost+found’: Permission denied
find: ‘/home/eexpss/磁盘/eexp/.gvfs’: Permission denied
/home/eexpss/.vim -> /home/eexpss/bin/config/.vim
/home/eexpss/.gitconfig -> /home/eexpss/bin/config/.gitconfig

I will accept Stéphane Chazelas' answer. thanks.

  • What did you try? – Satō Katsura Mar 27 '17 at 9:26
  • Do you want to list all symlinks in your home? Or only those that link to files on a different file system or outside your home? – Stéphane Chazelas Mar 27 '17 at 10:49
  • Note that -lname '/home/eexpss/bin/config/*' would not find relative symlinks that point inside ~/bin/config (like a /home/eexpss/x -> bin/config/x or /home/eexpss/etc/x -> ../bin/config/x), or those expressed as -> /home/eexpss/./bin/config/x or /home/eexpss/x/y where x is a symlink to bin/config, etc. – Stéphane Chazelas Mar 27 '17 at 12:31
  • $f would be expanded by the shell to the content of the $f shell variable. Possibly you meant %f (file name without leading path components)? – Stéphane Chazelas Mar 27 '17 at 12:33
  • my mistake, type %p as $p. lol. – eexpress Mar 27 '17 at 12:35

Standard find can't print any information about the found files by themselves except for their full paths. Some find implementations have extensions for that though.

For example, with GNU find (as found on most generic/traditional GNU/Linux distributions):

find ~ -type l -printf '%p -> %l\n'

Will print the symlinks in the format you're asking for, for symlinks found recursively (doing a physical traversal, that is not following symlinks to directories) in your home directory. Some find implementations also have a -ls predicate to output in a format similar to ls -li from which you may be able to extract the information.

If you wanted to do a logical traversal (follow symlinks to directories) and print that information, you couldn't do that with one find invocation alone (even with GNU find), but you could use zsh's globbing to traverse the directories instead and use GNU find only to print the information:

find ~/***/*(D@) -printf '%p -> %l\n'

Or with any shell and GNU find (but several invocations):

find -L ~ -xtype l -exec sh -c '
  exec find "$@" -printf "%p -> %l\n"' sh {} +

To find the symlinks that eventually point to some existing file in ~/bin/config (assuming that none of the components of ~/bin/config are symlinks themselves), still with zsh:

find ~/**/*(D@e{'[[ $REPLY:A = ~/bin/config/* ]]'}) -printf '%p -> %l\n'
  • -L will make find error: a system loop detect. your last example is too complex to understand. I just use -lname, that's OK. thanks. – eexpress Mar 27 '17 at 12:45

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.