Find all symbolic links pointing to a file
iMac, Mac OS X (10.6.4), 3.2 GHz Intel Core i3, 4 GB RAM
iMac, Mac OS X (10.6.4), 3.2 GHz Intel Core i3, 4 GB RAM
find -L / -samefile /path/to/real_file
#!/usr/bin/env bash
if [[ $# != 2 ]]; then
echo 1>&2 "Usage: ${0##*/} /starting_directory /path/to/reference_file"
exit 1
fi
START="$1"
export REFFILE="$2"
find $START -type l | perl -ne '
if ( ! $initialized ) {
$initialized = 1;
$reffile = $ENV{"REFFILE"};
@ref = stat($reffile);
}
chomp;
@st = stat($_);
if ( $st[0] == $ref[0] && $st[1] == $ref[1] ) {
print `ls -l "$_"`;
}
'
sudo -s
find / -type l -print0 | xargs -0 ls -TalkOs | sudo grep ' ->' | grep {filenameOfRealFile}
iMac:jv imac$ sudo -s
Password:
iMac:jv root# find / -type l -print0 | xargs -0 ls -TalkOs | grep ' -> ' | grep diskPM
4 lrwxr-xr-x 1 root wheel - 17 Jul 12 21:42:30 2010 /private/etc/periodic/weekly/600.diskPM -> /usr/local/diskPM
#!/usr/bin/env bash
if [[ $# != 2 ]]; then
echo 1>&2 "Usage: ${0##*/} /starting_directory /path/to/reference_file"
exit 1
fi
START="$1"
REFFILE="$2"
perl -e '
use File::Find;
@ref = stat($ARGV[1]);
find sub {
@st = stat($File::Find::name);
if ( $st[0] == $ref[0] && $st[1] == $ref[1] ) {
print `ls -l "$_"`;
}
}, $ARGV[0];
' "$START" "$REFFILE"
j.v. wrote:
find / -type l -print0 | xargs -0 ls -TalkOs | grep ' -> ' | grep diskPM
find / -type l -ls | grep ' -> ' | grep diskPM
find / -type l -ls
I think that this is equivalent to
find / -type l -ls | grep ' -> ' | grep diskPM
sudo find / -type l -ls | grep ' -> .*diskPM'
If you want to optimize, then why 2 grep's?
But j.v. still had more straight forward solution, and easier to understand then my install GNU 'find', or use perl (but I had fun writing the perl 🙂 ).
sudo find / -type l -ls
The approaches that use pipes will break on names containing whitespace, whereas find's -exec switch will handle them correctly.
find / -type l -ls | fgrep "filename"
Actually, running an exec and test for each link does not seem efficient at all.
time find $HOME -type l -exec test {} -ef /path/to/filename ; -print
real 1m18.780s
user 0m2.802s
sys 0m13.433s
time find $HOME -type l -ls | fgrep filename
real 1m12.950s
user 0m1.906s
sys 0m9.517s
time perl -e '...' # actually script posted above
real 2m16.701s
user 0m13.912s
sys 0m56.181s
find / -type l -ls | fgrep "filename"
is not only more efficient, but will list partial filenames (why test for "Very Long Path To/A Very Long File Created By Tony.txt" when an fgrep for "Tony" will do
MacBook:~ Tony$ sudo time find / -type l -ls | fgrep "test.txt"
Password:
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
10473:6413779 8 lrwxr-xr-x 1 Tony staff 8 Sep 18 20:29 /Users/Tony/test2.txt -> test.txt
238.97 real 3.81 user 51.58 sys
MacBook:~ Tony$ sudo time find / -type l -exec test {} -ef "test.txt" ; -print
Password:
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
/Users/Tony/test2.txt
243.92 real 8.71 user 71.88 sys
MacBook:~ Tony$
Find all symbolic links pointing to a file