I had folders with many symbolic links in them. Unfortunately after copying that around different filesystems, they've turned into plain text files with the link target as the contents. That is:


$ ll link
... link -> /path/to/target


$ cat link

What's the easiest way to restore this link? Perhaps a one-liner or a shell script.

Suppose I had hundreds of links like this, is there a way to restore them all, without manually running the fix on each one?

  • Get comfy with debugfs. Try to not cause too much damage... – Ignacio Vazquez-Abrams Aug 31 '13 at 1:36
  • debugfs is absolutely not the right tool to use here. – wingedsubmariner Aug 31 '13 at 4:10
  • Out of curiosity, which filesystems did you copy between, and what tools did you use? – wingedsubmariner Aug 31 '13 at 4:20

Use this command:

ls *txt | xargs -I R1 sh -c "cat R1 | xargs -I R2 ln -sf R2 R1"

Replace ls *txt with something that will output the list of text files that should be symbolic links. For example, find . -name "*txt" would list all *txt files in or under the current directory.


Try this:

ls * | while read f; do
  ln -sf "$(cat $f)" "$f" 

as in wingedsubmariner's answer, ls * should be replaced with something that will list exactly the files you wanted.

I find the

ls * | while read f; do
  # command executed for each file

construct very useful. As I know, this is the right way to handle all file names, e.g. if a file name has spaces then "$f" will still work (unlike with for f in $(ls *); do...done).

FYI: $(cmd) is the same as cmd but it can be nested unlike ``.

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.