0

I would like to transverse my home folder and list all symbolic links which point to element having Dropbox in their path. The following command (plus some post processing to remove additional field of info, but that should not be difficult) nearly accomplishes the task

ls -alR ~ | grep -e "->" | grep Dropbox

In the output of my ls, the marker -> precedes the path to the target of the symbolic link. In order to only get symbolic links pointing to something in Dropbox I pass the output through the final grep. However there is a problem: this way I only get the name of the symbolic link and not its full path. On the other hand using a command like:

ls -alR ~ | grep -e "->" | grep -E '(Dropbox|:)'

to keep the path listing of ls (in recursive searches ls first outputs the folder being listed followed by a colon) results in far too many hits. Any ideas?

7
  • 1
    Beware of the difficulties of parsing ls output if you have to deal with hostile file names (ones containing, for example, -> or newline or even blanks and tabs sometimes). Commented Nov 30, 2013 at 16:00
  • Yes, this is why you should always use a real programming language (i.e. not shell scripts) for writing business software. But for a quick personal script this is probably OK. Commented Nov 30, 2013 at 16:10
  • Right, there should not be too hostile files, it is for personal use. How do I highlight code portion in a message? I have seen you have done it for me, thanks!
    – GFR
    Commented Nov 30, 2013 at 16:12
  • Highlighting of code — indent by (at least) 4 spaces. To do it quickly, select the code you want to indent, then press the {} button above the edit box. (Rumours exist that control-K combination does it too; I've not used it.) Commented Nov 30, 2013 at 16:16
  • If you want to see hostile files, try running this script (in a junk directory — not one with valuable data in it): ls -la | while read -r line1 && read -r line2; do cp /dev/null $'\n'"$line1"$'\n'"$line2"; done. It works 'better' if you've got symlinks in the directory. It pretty much guarantees that naïve shell scripts will fail horribly. Commented Nov 30, 2013 at 16:18

1 Answer 1

1
find -type l -print0|xargs -0 ls -ld|grep Dropbox
5
  • 2
    I suggest adding -d to the ls options so that if the symlink points to a directory, you don't get a listing of the directory. You could also consider find ~ -type l -exec ls -ld {} + | grep Dropbox. Commented Nov 30, 2013 at 16:01
  • @JonathanLeffler thanks, forgot about the -d option - I've incorporated it into my answer. Commented Nov 30, 2013 at 16:03
  • 1
    Thanks Robin. Nearly there but it also lists files which have Dropbox in the path of the link rather than the target. I have tried modifying grep Dropbox to grep -E '.*->.*Dropbox' but it does not work - I do not know why. Playing around I have found that ls -l $(find ~ -type l) 2> /dev/null | grep -E '.*->.*Dropbox' > ~/Desktop/output.txt works even if it is not very clean: ls complains about some stuff being not existent so I sent stderror to /dev/null
    – GFR
    Commented Nov 30, 2013 at 16:08
  • 1
    Actually my solution indeed fails on filenames containing spaces. Jonathan answer with the change I proposed on the last grep seems what is working best for me: find ~ -type l -exec ls -ld {} + | grep Dropbox .
    – GFR
    Commented Nov 30, 2013 at 16:19
  • OK, it was a team effort! :) Commented Nov 30, 2013 at 16:20

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