only show the source file and target linked file using `ls`
Solution 1
ls
unfortunately doesn't have an option to retrieve file attributes and display them in an arbitrary way. Some systems have separate commands for that (for instance GNU has a stat
command or the functionality in GNU find
).
On most modern systems, with most files, this should work though:
$ ln -s '/foo/bar -> baz' the-file
$ LC_ALL=C ls -ldn the-file | sed '
1s/^\([^[:blank:]]\{1,\}[[:blank:]]\{1,\}\)\{8\}//'
the-file -> /foo/bar -> baz
That works by removing the first 8 blank delimited fields of the first line of the output of ls -l
. That should work except on systems where the gid is not displayed there or the first 2 fields are joined together when there's a large number of links.
With GNU stat
:
$ LC_ALL=C stat -c '%N' the-file
'the-file' -> '/foo/bar -> baz'
With GNU find
:
$ find the-file -prune \( -type l -printf '%p -> %l\n' -o -printf '%p\n' \)
the-file -> /foo/bar -> baz
With FreeBSD/OS/X stat:
f=the-file
if [ -L "$f" ]; then
stat -f "%N -> %Y" -- "$f"
else
printf '%s\n' "$f"
fi
With zsh
stat:
zmodload zsh/stat
f=the-file
zstat -LH s -- "$f"
printf '%s\n' ${s[link]:-$f}
Many systems also have a readlink
command to specifically get the target of a link:
f=the-file
if [ -L "$f" ]; then
printf '%s -> ' "$f"
readlink -- "$f"
else
printf '%s\n' "$f"
fi
Solution 2
Use the file
command.
[sreeraj@server ~]$ ls -l mytest
lrwxrwxrwx 1 sreeraj sreeraj 15 Dec 12 09:31 mytest -> /usr/sbin/httpd
[sreeraj@server ~]$ file mytest
mytest: symbolic link to `/usr/sbin/httpd'
or
[sreeraj@server ~]$ file -b mytest
symbolic link to `/usr/sbin/httpd'
[sreeraj@server ~]$
Also, please go read through man page of ls
and check the options -L
and -H
and see if that would suffice your requirement.
Solution 3
With a GNU ls
at least (and, apparently, tcsh
's implementation) you can hack the $LS_COLORS
environment variable to insert delimiters where you like (but tcsh
's builtin ls-F
doesn't do link targets - only link flags) Usually ls
inserts arbitrary non-printable terminal escapes based on the values stored within that environment var, but there's nothing stopping us from inserting arbitrary anything else instead. More on this here.
For example:
LS_COLORS='ln=///\n:lc=:no=//:rc=:rs=:' \
\ls ~ -l --color=always |
sed '\|///|,\|//|!d;//d'
That puts a string like //
at the head of every listing (so just before lrwcrwx
) and a ///\n
just before the filename of any link. sed
then filters on line ranges - it will d
elete every input line until it encounters ///
and from there through the next line which matches //
it will delete lines matching //
. So it only gets the link name and link target - regardless of intervening characters. This is because /
can't occur in a filename - and those in any path ls
might print will only occur singly.
See?
mkdir test; cd test
touch 'long
name' shortname
ln -s l* "$(printf %s.ln l*)"; ln -s s* shortname.ln
LS_COLORS='ln=///\n:lc=:no=//:rc=:rs=:' \
\ls -l --color=always | sed '\|///|,\|//|!d;//d'
...which prints:
long
name.ln -> long
name
shortname.ln -> shortname
Try it yourself.
Related videos on Youtube
![Chris Snow](https://i.stack.imgur.com/I6uGA.png?s=256&g=1)
Chris Snow
Updated on September 18, 2022Comments
-
Chris Snow almost 2 years
I can show the target file that a link points to using
ls -l
:snowch$ ls -l /usr/local/bin/mvn lrwxr-xr-x 1 snowch admin 29 12 Dec 08:58 /usr/local/bin/mvn -> ../Cellar/maven/3.2.3/bin/mvn
Is there a way to show less output without having to pipe through another command such as awk? E.g:
snowch$ ls ?? /usr/local/bin/mvn /usr/local/bin/mvn -> ../Cellar/maven/3.2.3/bin/mvn
I'm running 3.2.53 on OS X 10.9.5. The output from several commands is shown below:
snowch$ ls -H /usr/local/bin/mvn /usr/local/bin/mvn snowch$ ls -L /usr/local/bin/mvn /usr/local/bin/mvn snowch$ file /usr/local/bin/mvn /usr/local/bin/mvn: POSIX shell script text executable snowch$ file -b /usr/local/bin/mvn POSIX shell script text executable
-
rob over 9 yearscool, learn something new every day.
-
Chris Snow over 9 years@Sree - Many thanks! I had tried the
ls
options, but notfile
. Unfortunately, neither seems to work :( -
Sreeraj over 9 years@SHC Sorry, I assumed that you are on a
linux
box. Please addosx
as one of your tags. That should get to the attention ofosx
users as well. I have edited the post to add the tag, but I don't have enough credits for the edit to appear immediately. -
Chris Snow over 9 years@Sree - no worries, and sorry for the confusion. I've upvoted your answer anyway as it will be useful when I'm back on a linux machine.
-
tonioc over 9 yearsmaybe check 'readlink' utility on osx.
-
Chris Snow over 9 years
stat -f "%N -> %Y" -- /usr/local/bin/mvn
worked great. Thanks! -
Stéphane Chazelas over 9 yearsDo you know of any implementation besides modern versions of GNU
ls
that supportsLS_COLORS
that way and a--color=always
and options after arguments? If on a GNU system, why would you use something that convoluted when you can usefind
orstat
? That also probably won't work if you do someln -s /// some-file
. -
mikeserv over 9 years@StephaneChezales - this indicates at least that it should work similarly with a bsd
ls
. I remember reading that somewhere else months ago aboutls
s all tending to accept a termcap like syntax. Good point about theln -s ///
thing - but\0
NULs work as well - and-R
ecursively. As to why - well, it's easy to use. In some cases easier thanfind
- and it seemed a little more on topic here thanfind
would have been. In any case, not too many people consider it, so I mention it when I'm reminded. -
Stéphane Chazelas over 9 yearsSee the man page or there for FreeBSD. If you want to test things on FreeBSD, you can use live CDs like GhostBSD/mfsbsd in a VM.
-
mikeserv over 9 years@StéphaneChazelas - no, i dont need to test it - definitely a wholly different animal. If you care to look, the gnu source is also linked to in the link in this answer. i wonder where i read that other thing? thanks very much for pointing that out though, that was a mistaken assumption im happy to discard. ive edited the answer.
-
Stéphane Chazelas over 9 yearsrecent versions of
tcsh
have als-F
builtin that supportsLS_COLORS
the same way as some versions of GNUls
, but it resorts to invokingls -F
if you pass any option to it, so that won't work here unlessls
is GNUls
on your system. -
mikeserv over 9 years@StéphaneChazelas - what do you mean by that exactly - sorry i dont follow this one...? i only wrote it in because in the same google search with which i found bsd's source i also found tcsh's env docs. theyre pretty eplicit there about how it should be used - moreso than the gnu folks - most of what the tcsh docs say i gathered from the gnu source. it seems weird they would be so explicit in a shell doc about a possibly unrelated command.
-
mikeserv over 9 years@StéphaneChazelas - ok. so you mean
--color-always
and$color
probably. it might still work, though, one would have to be pretty devoted to doing it. a tty in between would be necessary i guess - maybe just aexec 3<>/dev/tty
beforehand - (iftcsh
will do it, classiccsh
s probably wouldnt). as i said before, i only wrote it up at all because it seemed relevant - and it can be handy in different ways for noting different file-types/extensions with different delims (or different numbers of such) especially for extensns -
Stéphane Chazelas over 9 yearsYou need
-l
to retrieve the symlink target, sols-F
won't do. -
mikeserv over 9 years@StéphaneChazelas - oh. duh.
ls-F
makes that obvious enough, I guess. guess it just didn't occur to me what they'd do anls
that didn't dols
stuff. -
Jeff Schaller almost 9 yearsThe question explicitly stated "... without having to pipe through another command ..."
-
user2332706 almost 9 years@JeffSchaller: Good point; I agree. I hope, though, that this is still of use to someone wanting an answer to the title question (without the detail in the description).
-
cfi almost 8 yearsOn an old RHEL6 system, stat is of GNU coreutils 8.4 and there it's a
stat -c %N -- /usr/local/bin/mvn
. To remove the quotations I had to pipe this into| perl -pe 's/['"'"'`]//g'
-
Stéphane Chazelas almost 8 years@cfi
tr -d \'\`
would be enough. Note that that RHEL system would have GNUfind
with which you'll have more control over.