Symbolic Link: Find All Files That Link to This File

symbolic link: find all files that link to this file

It depends, if you are trying to find links to a specific file that is called foo.txt, then this is the only good way:

find -L / -samefile path/to/foo.txt

On the other hand, if you are just trying to find links to any file that happens to be named foo.txt, then something like

find / -lname foo.txt

or

find . -lname \*foo.txt # ignore leading pathname components

How to find all symlinks to a file?

If you have GNU/BSD find just use -samefile primary.

$ find -L ~/Symbolic Link: Find All Files That Link to This File/ -samefile ~/Symbolic Link: Find All Files That Link to This File/q/a.txt 
/home/oguz/Symbolic Link: Find All Files That Link to This File/q/a.txt
/home/oguz/Symbolic Link: Find All Files That Link to This File/w/l2
/home/oguz/Symbolic Link: Find All Files That Link to This File/w/l1

Find broken symbolic link then find respective file in backup and relink

It's not the prettiest, but it works.

find . -type l | while read f
do
if [ ! -e "$f" ] #if link is broken
then
item=$(ls -l "$f")
filepath=$(echo "$item" | sed -n 's/^.* \.\/\s*\(\S*\).*$/\1/p') #extract filepath by looking for " ./"
oldlinkpath=$(echo "$item" | sed -n 's/^.*>\s*\(\S*\).*$/\1/p') #extract linkpath by looking for ">"
oldlinkfilename=$(basename "$oldlinkpath")
newlinkpath=$(find /mnt/usbbackup/ppgdata/data -type f -name "$oldlinkfilename") #find file in backup
rm "$filepath" #remove symlink
echo "linking $filepath to $newlinkpath"
ln -s "$newlinkpath" "$filepath" #create new symlink to file in backup
fi
done
  1. find all the broken links
  2. extract path of broken link
  3. find filename of linked file
  4. find linked file in backup by its filename
  5. change link to location in backup

Once all is done I run 'symlinks -c folder' to change all the absolute paths to relative ones.

Linux: Find all symlinks of a given 'original' file? (reverse 'readlink')

I've not seen a command for this and it's not an easy task, since the target file contains zero information on what source files point to it.

This is similar to "hard" links but at least those are always on the same file system so you can do a find -inode to list them. Soft links are more problematic since they can cross file systems.

I think what you're going to have to do is basically perform an ls -al on every file in your entire hierarchy and use grep to search for -> /path/to/target/file.

For example, here's one I ran on my system (formatted for readability - those last two lines are actually on one line in the real output):

pax$ find / -exec ls -ald {} ';' 2>/dev/null | grep '\-> /usr/share/applications'
lrwxrwxrwx 1 pax pax 23 2010-06-12 14:56 /home/pax/applications_usr_share
-> /usr/share/applications

Find symlink using Find in Perl

The File::Find::Rule implements the -X filetests, as methods. The one that tests whether an entry is a symlink (-l) is called symlink.

In my reading of the question you don't know the name of that directory (otherwise, why "find" a file in it?), except that it is a symbolic link. Then you need to first find directories which are symlinks, then find files in them. For this second task you'll need to tell the module to follow the links.

I use a test structure on disk


test_find/a/c/c.txt
test_find/a/b/b.txt
test_find/is_link -> a/c ("is_link" is a symbolic link to "a/c")

and from the directory right above it I run the program

use warnings;
use strict;
use feature 'say';

use File::Find::Rule;

my $top_dir = shift @ARGV || './test_find';

my @symlink_dirs = File::Find::Rule->directory->symlink->in($top_dir);

foreach my $dir (@symlink_dirs) {
my @files = File::Find::Rule->file->extras({follow => 1})->in($dir);
say "in $dir: @files";
}

which prints


in test_find/is_link: test_find/is_link/c.txt

Note that the program will find all files in all directories which are symlinks. Writing an explicit loop as above allows you to add code to decide which of the symlink-directories to actually search. If you don't mind looking through all of them you can just do

my @files = File::Find::Rule->file->extras({follow => 1})->in(@symlink_dirs);

See documentation for features to limit the search using what you know about the directory/file.


If the link directory is in a hierarchy not including the target, then simply search that hierarchy.

With test structure


other_hier/is_link -> ../test_find/a/c
test_find/a/c/c.txt

you only need to tell it to follow the links

my @all_files = File::Find::Rule  # may use linebreaks and spaces
-> file
-> extras({ follow => 1 })
-> in('other_hier');

When added to the above program and printed this adds


another/is_link/c.txt

You can of course replace the literal 'other_hier' with $top_dir and invoke the program with argument other_hier (and make that other_hier directory and the link in it).

If both link and target are in the same hierarchy that is searched then you can't do this; the search would run into circular links (the module detects that and exits with error).

How to list files/directories where there are symbolic links

Everyone's input helped me narrow down and figure out the problem. I believe the issue is that I had deleted the target of a symbolic link, but my recursive delete function still found it to be a directory. So when I tried to enumerate the files/directories of that symbolic link it threw a DirectoryNotFound exception (which is definitely confusing to encounter there because the directory still appears to exist - even in the file explorer, until you click on it).

The solution is that when trying to gather the children of a directory, catch DirectoryNotFound exceptions and try to delete the directory instead. That worked for me

        FileInfo[] files = null;
try
{
files = currentDirectory.GetFiles("*", SearchOption.AllDirectories);
}
catch (DirectoryNotFoundException)
{
currentDirectory.Delete(true);
}


Related Topics



Leave a reply



Submit