afficher uniquement le fichier source et le fichier lié cible en utilisant `ls`

11

Je peux montrer le fichier cible qu'un lien pointe vers l'utilisation 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

Existe-t-il un moyen d'afficher moins de sortie sans avoir à passer par une autre commande telle que awk? Par exemple:

snowch$ ls ?? /usr/local/bin/mvn
/usr/local/bin/mvn -> ../Cellar/maven/3.2.3/bin/mvn

J'utilise 3.2.53 sur OS X 10.9.5. La sortie de plusieurs commandes est illustrée ci-dessous:

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
Chris Snow
la source

Réponses:

7

lsn'a malheureusement pas d'option pour récupérer les attributs de fichier et les afficher de manière arbitraire. Certains systèmes ont des commandes distinctes pour cela (par exemple GNU a une statcommande ou la fonctionnalité dans GNU find).

Sur la plupart des systèmes modernes, avec la plupart des fichiers, cela devrait fonctionner cependant:

$ 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

Cela fonctionne en supprimant les 8 premiers champs délimités par des blancs de la première ligne de la sortie de ls -l. Cela devrait fonctionner sauf sur les systèmes où le gid n'y est pas affiché ou les 2 premiers champs sont réunis lorsqu'il y a un grand nombre de liens.

Avec GNU stat:

$ LC_ALL=C stat -c '%N' the-file
'the-file' -> '/foo/bar -> baz'

Avec GNU find:

$ find the-file -prune \( -type l -printf '%p -> %l\n' -o -printf '%p\n' \)
the-file -> /foo/bar -> baz

Avec FreeBSD / OS / X stat:

f=the-file
if [ -L "$f" ]; then
  stat -f "%N -> %Y" -- "$f"
else
  printf '%s\n' "$f"
fi

Avec zshstat:

zmodload zsh/stat
f=the-file
zstat -LH s -- "$f"
printf '%s\n' ${s[link]:-$f}

De nombreux systèmes ont également une readlinkcommande pour obtenir spécifiquement la cible d'un lien:

f=the-file
if [ -L "$f" ]; then
  printf '%s -> ' "$f"
  readlink -- "$f"
else
  printf '%s\n' "$f"
fi
Stéphane Chazelas
la source
stat -f "%N -> %Y" -- /usr/local/bin/mvna très bien fonctionné. Merci!
Chris Snow
1
Sur un ancien système RHEL6, stat est de GNU coreutils 8.4 et là c'est a stat -c %N -- /usr/local/bin/mvn. Pour supprimer les citations, je devais en | perl -pe 's/['"'"'`]//g'
parler
@cfi tr -d \'\`serait suffisant. Notez que ce système RHEL aurait GNU findavec lequel vous aurez plus de contrôle.
Stéphane Chazelas
5

Utilisez la filecommande.

[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'

ou

[sreeraj@server ~]$ file -b mytest
symbolic link to `/usr/sbin/httpd'
[sreeraj@server ~]$

En outre, s'il vous plaît aller lire la page de manuel de lset vérifiez les options -Let -Hvoir si cela suffira à vos besoins.

Sree
la source
cool, apprenez quelque chose de nouveau chaque jour.
voler
@Sree - Merci beaucoup! J'avais essayé les lsoptions, mais non file. Malheureusement, ni l'un ni l'autre ne semble fonctionner :(
Chris Snow
@SHC Désolé, je suppose que vous êtes sur une linuxboîte. Veuillez ajouter l' osxun de vos tags. Cela devrait également attirer l'attention des osxutilisateurs. J'ai modifié le post pour ajouter le tag, mais je n'ai pas assez de crédits pour que le montage apparaisse immédiatement.
Sree
@Sree - pas de soucis et désolé pour la confusion. J'ai quand même voté pour votre réponse car elle sera utile lorsque je serai de retour sur une machine Linux.
Chris Snow
peut-être vérifier l'utilitaire «readlink» sur osx.
tonioc
2

Avec un GNU lsau moins (et, apparemment, tcshl'implémentation), vous pouvez pirater la $LS_COLORSvariable d'environnement pour insérer des délimiteurs où vous le souhaitez (mais tcshla fonction intégrée ls-Fne fait pas de cibles de lien - seulement des indicateurs de lien )ls Insère généralement des échappements de terminal arbitraires non imprimables basé sur les valeurs stockées dans cet environnement var, mais rien ne nous empêche d'insérer quoi que ce soit d'autre à la place. Plus à ce sujet ici .

Par exemple:

LS_COLORS='ln=///\n:lc=:no=//:rc=:rs=:' \
\ls ~ -l --color=always | 
sed '\|///|,\|//|!d;//d'

Cela met une chaîne comme //en tête de chaque liste (donc juste avant lrwcrwx) et ///\njuste avant le nom de fichier de tout lien. sedpuis filtre sur les plages de lignes - il dsupprimera chaque ligne d'entrée jusqu'à ce qu'il rencontre ///et à partir de là jusqu'à la ligne suivante qui correspond, //il supprimera les lignes correspondantes //. Il n'obtient donc que le nom du lien et la cible du lien, quels que soient les caractères intermédiaires. C'est parce que /ne peut pas se produire dans un nom de fichier - et ceux dans n'importe quel chemin lspeuvent imprimer ne se produiront que séparément.

Voir?

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'

... qui imprime:

long


name.ln -> long


name
shortname.ln -> shortname

Essayez-le vous-même.

mikeserv
la source
Connaissez-vous une implémentation en plus des versions modernes de GNU lsqui prend en charge de LS_COLORScette façon et a --color=alwayset les options après les arguments? Si sur un système GNU, pourquoi utiliseriez-vous quelque chose de compliqué quand vous pouvez utiliser findou stat? Cela ne fonctionnera probablement pas non plus si vous en faites ln -s /// some-file.
Stéphane Chazelas
@StephaneChezales - cela indique au moins qu'il devrait fonctionner de manière similaire avec un bsd ls. Je me souviens avoir lu il y a des mois quelque part ailleurs à propos de lstous qui ont tendance à accepter une syntaxe similaire à celle d'un termcap. Bon point à propos de la ln -s ///chose - mais les \0NUL fonctionnent également - et de manière -Récursive. Quant à savoir pourquoi - c'est facile à utiliser. Dans certains cas, plus facile que find- et cela semblait un peu plus sur le sujet ici qu'il findn'aurait été. En tout cas, pas trop de gens le considèrent, donc je le mentionne quand on me le rappelle.
mikeserv
Voir la page de manuel ou pour FreeBSD. Si vous voulez tester des choses sur FreeBSD, vous pouvez utiliser des CD live comme GhostBSD / mfsbsd dans une VM.
Stéphane Chazelas
@ StéphaneChazelas - non, je n'ai pas besoin de le tester - certainement un animal complètement différent . Si vous voulez regarder, la source gnu est également liée au lien dans cette réponse. je me demande où j'ai lu cette autre chose? merci beaucoup de l'avoir souligné cependant, c'était une hypothèse erronée que je suis heureux de rejeter. ive a édité la réponse.
mikeserv
les versions récentes de tcshont une fonction ls-Fintégrée qui prend en charge LS_COLORSla même manière que certaines versions de GNU ls, mais elle a recours à l'invocation ls -Fsi vous lui passez une option, de sorte que cela ne fonctionnera pas à moins que lsGNU ne soit lssur votre système.
Stéphane Chazelas
-1

[Sous Linux / Bash]

Je ferais ceci:

ls -l | sed -e"s/ \+/ /g" | cut -d' ' -f 9-

La sedcommande réduit plusieurs espaces en un seul espace; le cutextrait le 9ème champ à partir de là où le séparateur de champ est un espace.

Sortie typique de ceci:

libboost_atomic.a
libboost_atomic.so -> libboost_atomic.so.1.57.0
libboost_atomic.so.1.57.0
...
libboost_wserialization.a
libboost_wserialization.so -> libboost_wserialization.so.1.57.0
libboost_wserialization.so.1.57.0

Les alternatives sont:

ls -l | awk '{ print $9, $10, $11 }'
ls -l | awk '{ $1 = $2 = $3 = $4 = $5 = $6 = $7 = $8 = "" ; print }'

Mais ceux-ci sont imparfaits: le premier peut produire des espaces de fin; le second, menant des espaces.

Rhubbarb
la source
La question indiquait explicitement "... sans avoir à passer par une autre commande ..."
Jeff Schaller
@JeffSchaller: Bon point; Je suis d'accord. J'espère, cependant, que cela est toujours utile à quelqu'un qui veut une réponse à la question du titre (sans le détail dans la description).
Rhubbarb