показуйте лише вихідний файл та пов'язаний з ним файл, використовуючи `ls`


11

Я можу показати цільовий файл, на який посилання вказує, використовуючи 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

Чи є спосіб показати менший вихід без необхідності передавати іншу команду, таку як awk? Наприклад:

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

Я працюю 3.2.53 на OS X 10.9.5. Вихід з декількох команд показаний нижче:

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

Відповіді:


7

lsна жаль, немає можливості отримати атрибути файлів і відобразити їх довільним чином. Деякі системи мають для цього окремі команди (наприклад, GNU має statкоманду або функціонал у GNU find).

У більшості сучасних систем із більшості файлів це повинно працювати:

$ 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

Це працює, видаляючи перші 8 порожніх розділених полів першого рядка виводу ls -l. Це повинно працювати, за винятком систем, де gid не відображається там або перші 2 поля з'єднуються разом, коли існує велика кількість посилань.

З GNU stat:

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

З GNU find:

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

З станом FreeBSD / OS / X:

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

Зі zshстатистикою:

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

У багатьох системах також є readlinkкоманда спеціально отримати ціль посилання:

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/mvnпрацював чудово. Дякую!
Кріс Сноу

1
У старій системі RHEL6 stat є GNU coreutils 8.4, і там він є stat -c %N -- /usr/local/bin/mvn. Щоб вилучити цитати, мені довелося | perl -pe 's/['"'"'`]//g'
переказати

@cfi tr -d \'\`було б досить. Зауважте, що ця система RHEL матиме GNU, findз яким ви матимете більше контролю над.
Стефан Шазелас

5

Використовуйте fileкоманду.

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

або

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

Також, будь ласка, перегляньте сторінку man lsі перевірте параметри -Lта перевірте -H, чи вистачить цього вашої вимоги.


круто, щодня дізнайся щось нове.
грабувати

@Sree - велике спасибі! Я спробував lsваріанти, але ні file. На жаль, ні одне, здається, не працює :(
Кріс Снож

@SHC Вибачте, я припустив, що ви на linuxкоробці. Будь ласка, додайте osxяк один із ваших тегів. Це має привернути увагу і osxкористувачів. Я відредагував публікацію, щоб додати тег, але мені не вистачає кредитів, щоб редагування з’явилося негайно.
Sree

@Sree - не хвилюйтесь, і вибачте за плутанину. Я все-таки підтримав вашу відповідь, оскільки це буде корисно, коли я знову на машині Linux.
Кріс Сноу

можливо, перевірте утиліту «readlink» на OSX.
tonioc

2

lsПринаймні з GNU (і, мабуть, tcshз реалізацією) ви можете зламати $LS_COLORSзмінну середовища, щоб вставити роздільники, де вам подобається (але tcshвбудований ls-Fне робить цілі посилань - лише прапори посилань ) Зазвичай lsвставляє довільні недруковані термінали. на основі значень, що зберігаються в цьому середовищі var, але ніщо не заважає нам вставляти натомість будь-яке інше. Більше про це тут .

Наприклад:

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

Це ставить рядок як //на чолі кожного списку (так що раніше lrwcrwx) і ///\nбезпосередньо перед назвою файлу будь-якого посилання. sedпотім фільтрує діапазони рядків - він буде dвибирати кожен рядок входу, поки він не зустрінеться, ///а звідти через наступний рядок, який відповідає, //буде видалено відповідність рядків //. Таким чином, він отримує лише ім'я посилання та ціль посилання - незалежно від символів, що втручаються. Це відбувається тому, що /не може зустрічатися в імені файлу - і ті, які lsможуть бути надруковані, можуть відбуватися лише поодиноко.

Подивитися?

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'

... який друкує:

long


name.ln -> long


name
shortname.ln -> shortname

Спробуйте самі.


Чи знаєте ви про будь-яку реалізацію, окрім сучасних версій GNU, lsяка підтримує LS_COLORSцей спосіб, a --color=alwaysта варіанти після аргументів? Якщо в системі GNU, чому б ви використовували щось, що згорнулося, коли ви можете використовувати findабо stat? Це також, ймовірно, не буде працювати, якщо ви зробите щось ln -s /// some-file.
Стефан Шазелас

@StephaneChezales - це вказує принаймні на те, що він повинен працювати аналогічно bsd ls. Я пам’ятаю, як читав, що ще десь місяці тому про те, lsщо всі прагнуть прийняти термінальну назву, як синтаксис. Хороший момент про цю ln -s ///річ - але \0НУЛ також працює - і -Rекурсивно. Щодо того - ну, це просто у використанні. У деяких випадках простіше, ніж find- і тут здавалося трохи більше на тему, ніж findбуло б. У будь-якому випадку, не надто багато людей вважають це, тому я згадую про це, коли мені нагадають.
mikeserv

Дивіться сторінку людини або там для FreeBSD. Якщо ви хочете протестувати речі на FreeBSD, ви можете використовувати живі компакт-диски, такі як GhostBSD / mfsbsd, у віртуальній машині.
Стефан Шазелас

@ StéphaneChazelas - ні, мені не потрібно тестувати це - безумовно, зовсім інша тварина . Якщо ви хочете подивитися, джерело gnu також пов'язане з посиланням у цій відповіді. мені цікаво, де я читав ту іншу річ? велике спасибі за те, що наголосили, що це було помилковим припущенням, яке я радий відкинути. ive відредагував відповідь.
mikeserv

в останніх версіях tcshє ls-Fвбудований модуль, який підтримує LS_COLORSтак само, як і деякі версії GNU ls, але він вдається до виклику, ls -Fякщо ви передасте йому якийсь варіант, так що тут не буде працювати, якщо lsGNU не є lsу вашій системі.
Stéphane Chazelas

-1

[На Linux / Bash]

Я б це зробив:

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

sedКоманда розвалюється кілька прогалин в єдиному просторі; cutвитягує 9th поле і далі , де поле сепаратор являє собою простір.

Типовий вихід з цього:

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

Альтернативи:

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

Але це недосконало: перший може вивести пробіли; другий, провідний простір.


У запитанні прямо сказано "... без необхідності подавати іншу команду ..."
Jeff Schaller

@JeffSchaller: Добрий момент; Я згоден. Я сподіваюся, що це все-таки корисно для того, хто хоче відповісти на заголовок питання (без деталізації в описі).
Rhubbarb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.