mostra solo il file sorgente e il file collegato di destinazione usando `ls`


11

Posso mostrare il file di destinazione a cui punta un collegamento usando 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

C'è un modo per mostrare meno output senza dover passare attraverso un altro comando come awk? Per esempio:

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

Sto eseguendo 3.2.53 su OS X 10.9.5. L'output di diversi comandi è mostrato di seguito:

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

Risposte:


7

lspurtroppo non ha un'opzione per recuperare gli attributi di file e visualizzarli in modo arbitrario. Alcuni sistemi hanno comandi separati per questo (per esempio GNU ha un statcomando o la funzionalità in GNU find).

Sulla maggior parte dei sistemi moderni, con la maggior parte dei file, dovrebbe funzionare anche se:

$ 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

Funziona rimuovendo i primi 8 campi delimitati vuoti della prima riga dell'output di ls -l. Dovrebbe funzionare tranne nei sistemi in cui il gid non è visualizzato lì o i primi 2 campi sono uniti quando c'è un gran numero di collegamenti.

Con GNU stat:

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

Con GNU find:

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

Con le statistiche di FreeBSD / OS / X:

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

Con zshstat:

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

Molti sistemi hanno anche un readlinkcomando per ottenere specificamente l'obiettivo di un collegamento:

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

stat -f "%N -> %Y" -- /usr/local/bin/mvnha funzionato alla grande. Grazie!
Chris Snow,

1
Su un vecchio sistema RHEL6, stat è di GNU coreutils 8.4 e c'è a stat -c %N -- /usr/local/bin/mvn. Per rimuovere le citazioni ho dovuto inserire questo in| perl -pe 's/['"'"'`]//g'
cfi

@cfi tr -d \'\`sarebbe abbastanza. Nota che quel sistema RHEL avrebbe GNU findcon il quale avrai più controllo.
Stéphane Chazelas,

5

Usa il filecomando

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

o

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

Inoltre, si prega di andare a leggere attraverso la pagina di uomo del lse verificare le opzioni -Le -He vedere se questo sarebbe sufficiente la vostra esigenza.


bene, impara qualcosa di nuovo ogni giorno.
derubare il

@Sree - Mille grazie! Avevo provato le lsopzioni, ma non file. Sfortunatamente, nessuno dei due sembra funzionare :(
Chris Snow,

@SHC Mi dispiace, ho pensato che tu fossi su una linuxscatola. Aggiungi osxcome uno dei tuoi tag. Ciò dovrebbe attirare anche l'attenzione degli osxutenti. Ho modificato il post per aggiungere il tag, ma non ho abbastanza crediti per la modifica per apparire immediatamente.
Sree,

@Sree - nessuna preoccupazione, e scusate la confusione. Ho comunque votato la tua risposta in quanto sarà utile quando torno su una macchina Linux.
Chris Snow,

forse controlla l'utilità 'readlink' su osx.
tonioc,

2

lsAlmeno con una GNU (e, a quanto pare, tcshl'implementazione) puoi hackerare la $LS_COLORSvariabile d'ambiente per inserire delimitatori dove preferisci (ma tcshil builtin ls-Fnon fa target di link - solo flag di link ) Di solito lsinserisce escape arbitrari non stampabili del terminale basato sui valori memorizzati in quell'ambiente var, ma non c'è niente che ci impedisce di inserire qualsiasi altra cosa arbitraria. Maggiori informazioni qui .

Per esempio:

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

Questo mette una stringa come //all'inizio di ogni elenco (quindi appena prima lrwcrwx) e ///\nappena prima del nome file di qualsiasi collegamento. sedquindi filtra gli intervalli di riga: deliminerà ogni riga di input fino a quando non si incontra ///e da lì attraverso la riga successiva corrispondente corrisponde //a eliminare le righe corrispondenti //. Quindi ottiene solo il nome e la destinazione del collegamento, indipendentemente dai caratteri intermedi. Questo perché /non può verificarsi in un nome file e quelli in qualsiasi percorso lspotrebbero essere stampati solo.

Vedere?

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'

... che stampa:

long


name.ln -> long


name
shortname.ln -> shortname

Prova tu stesso.


Conoscete qualche implementazione oltre alle versioni moderne di GNU lsche supporta in LS_COLORSquel modo --color=alwayse opzioni e opzioni dopo? Se su un sistema GNU, perché dovresti usare qualcosa di contorto quando puoi usare findo stat? Anche questo probabilmente non funzionerà se ne fai un po ' ln -s /// some-file.
Stéphane Chazelas,

@StephaneChezales - questo indica almeno che dovrebbe funzionare in modo simile con un bsd ls. Ricordo di averlo letto altrove mesi fa lsche tutti tendevano ad accettare un termcap come la sintassi. Un buon punto a riguardo ln -s ///- ma anche i \0NUL funzionano - ed -Recursivamente. Sul perché - beh, è ​​facile da usare. In alcuni casi più facile di find- e qui sembrava un po 'più in tema di quanto findsarebbe stato. In ogni caso, non troppe persone lo considerano, quindi lo menziono quando mi viene ricordato.
Mikeserv,

Vedi la pagina man o per FreeBSD. Se vuoi testare cose su FreeBSD, puoi usare CD live come GhostBSD / mfsbsd in una VM.
Stéphane Chazelas,

@ StéphaneChazelas - no, non ho bisogno di provarlo - sicuramente un animale completamente diverso . Se ti interessa guardare, anche la fonte gnu è collegata al link in questa risposta. mi chiedo dove ho letto quell'altra cosa? grazie mille per averlo sottolineato, tuttavia, è stato un presupposto errato e felice di scartarlo. ho modificato la risposta.
Mikeserv,

le versioni recenti di tcshhanno un ls-Fbuilt-in che supporta LS_COLORSallo stesso modo di alcune versioni di GNU ls, ma ricorre a invocare ls -Fse gli passi qualsiasi opzione, quindi non funzionerà qui a meno che lsGNU non sia lssul tuo sistema.
Stéphane Chazelas,

-1

[Su Linux / Bash]

Farei questo:

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

Il sedcomando comprime più spazi in un unico spazio; la cutestrae il campo 9 in poi dove il campo-separatore è uno spazio.

Uscita tipica da questo:

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

Le alternative sono:

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

Ma quelli sono imperfetti: il primo può generare spazi finali; il secondo, spazi principali.


La domanda affermava esplicitamente "... senza dover eseguire un altro comando ..."
Jeff Schaller

@JeffSchaller: buon punto; Sono d'accordo. Spero, tuttavia, che questo sia ancora utile a qualcuno che desidera una risposta alla domanda del titolo (senza i dettagli nella descrizione).
Rabarbaro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.