hanya tampilkan file sumber dan file tertaut target menggunakan `ls`

11

Saya dapat menunjukkan file target yang ditunjukkan oleh tautan 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

Apakah ada cara untuk menunjukkan lebih sedikit output tanpa harus menyalurkan melalui perintah lain seperti awk? Misalnya:

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

Saya menjalankan 3.2.53 pada OS X 10.9.5. Output dari beberapa perintah ditunjukkan di bawah ini:

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
sumber

Jawaban:

7

lssayangnya tidak memiliki opsi untuk mengambil atribut file dan menampilkannya secara sewenang-wenang. Beberapa sistem memiliki perintah terpisah untuk itu (misalnya GNU memiliki statperintah atau fungsi di GNU find).

Pada kebanyakan sistem modern, dengan sebagian besar file, ini seharusnya bekerja:

$ 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

Itu bekerja dengan menghapus 8 bidang kosong terbatas pertama dari baris pertama dari output ls -l. Itu harus bekerja kecuali pada sistem di mana gid tidak ditampilkan di sana atau 2 bidang pertama digabungkan ketika ada banyak tautan.

Dengan GNU stat:

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

Dengan GNU find:

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

Dengan FreeBSD / OS / X stat:

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

Dengan zshstat:

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

Banyak sistem juga memiliki readlinkperintah untuk secara spesifik mendapatkan target tautan:

f=the-file
if [ -L "$f" ]; then
  printf '%s -> ' "$f"
  readlink -- "$f"
else
  printf '%s\n' "$f"
fi
Stéphane Chazelas
sumber
stat -f "%N -> %Y" -- /usr/local/bin/mvnbekerja dengan baik. Terima kasih!
Chris Snow
1
Pada sistem RHEL6 lama, stat dari GNU coreutils 8.4 dan itu ada stat -c %N -- /usr/local/bin/mvn. Untuk menghapus kutipan, saya harus | perl -pe 's/['"'"'`]//g'
mengirimkannya
@ cfi tr -d \'\`akan cukup. Perhatikan bahwa sistem RHEL akan memiliki GNU findyang dapat Anda kendalikan.
Stéphane Chazelas
5

Gunakan fileperintah.

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

atau

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

Juga, silakan pergi membaca halaman manual dari lsdan memeriksa pilihan -Ldan -Hdan melihat apakah yang akan cukup kebutuhan Anda.

Sree
sumber
keren, pelajari sesuatu yang baru setiap hari.
merampok
@Sree - Terima kasih banyak! Saya sudah mencoba lsopsi, tetapi tidak file. Sayangnya, sepertinya tidak ada yang bekerja :(
Chris Snow
@SHC Maaf, saya berasumsi bahwa Anda berada di linuxkotak. Silakan tambahkan osxsebagai salah satu tag Anda. Itu harus menjadi perhatian osxpengguna juga. Saya telah mengedit posting untuk menambahkan tag, tetapi saya tidak memiliki kredit yang cukup untuk pengeditan segera muncul.
Sree
@Sree - jangan khawatir, dan maaf untuk kebingungannya. Saya telah memutakhirkan jawaban Anda karena akan berguna ketika saya kembali ke mesin linux.
Chris Snow
mungkin periksa utilitas 'readlink' di osx.
tonioc
2

Dengan lssetidaknya GNU (dan, tampaknya, tcshimplementasi), Anda dapat meretas $LS_COLORSvariabel lingkungan untuk menyisipkan pembatas di tempat yang Anda suka (tetapi tcshbuiltin ls-Ftidak melakukan target tautan - hanya tanda tautan ) Biasanya lsmemasukkan terminal yang tidak dapat dicetak keluar secara sewenang-wenang. berdasarkan nilai-nilai yang disimpan dalam lingkungan itu var, tapi tidak ada yang menghentikan kita dari memasukkan apa pun yang sewenang-wenang. Lebih lanjut tentang ini di sini .

Sebagai contoh:

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

Itu menempatkan string seperti //di kepala setiap daftar (jadi sebelum lrwcrwx) dan ///\ntepat sebelum nama file tautan apa pun. sedkemudian filter pada rentang garis - itu akan dmenghapus setiap baris input sampai bertemu ///dan dari sana melalui baris berikutnya yang cocok //itu akan menghapus baris yang cocok //. Jadi itu hanya mendapatkan nama tautan dan target tautan - terlepas dari karakter yang mengintervensi. Ini karena /tidak dapat terjadi dalam nama file - dan mereka yang berada di jalur mana pun lsmungkin mencetak hanya akan muncul secara tunggal.

Lihat?

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'

... yang mencetak:

long


name.ln -> long


name
shortname.ln -> shortname

Cobalah sendiri.

mikeserv
sumber
Apakah Anda tahu implementasi apa pun selain versi modern GNU lsyang mendukung LS_COLORScara --color=alwaysdan opsi serta opsi setelah argumen? Jika pada sistem GNU, mengapa Anda menggunakan sesuatu yang berbelit-belit saat Anda dapat menggunakan findatau stat? Itu juga mungkin tidak akan berhasil jika Anda melakukan beberapa ln -s /// some-file.
Stéphane Chazelas
@StephaneChezales - ini menunjukkan setidaknya itu harus bekerja sama dengan bsd ls. Saya ingat pernah membaca bahwa di tempat lain berbulan-bulan yang lalu tentang lssemua cenderung menerima termcap seperti sintaks. Poin bagus tentang ln -s ///hal itu - tetapi \0NUL bekerja juga - dan secara -Rekologis. Seperti mengapa - yah, mudah digunakan. Dalam beberapa kasus lebih mudah daripada find- dan tampaknya lebih pada topik di sini daripada findseharusnya. Bagaimanapun, tidak terlalu banyak orang yang mempertimbangkannya, jadi saya menyebutkannya ketika saya diingatkan.
mikeserv
Lihat halaman manual atau di sana untuk FreeBSD. Jika Anda ingin menguji berbagai hal di FreeBSD, Anda dapat menggunakan CD langsung seperti GhostBSD / mfsbsd di VM.
Stéphane Chazelas
@ StéphaneChazelas - tidak, saya tidak perlu mengujinya - jelas binatang yang sama sekali berbeda . Jika Anda ingin melihatnya, sumber gnu juga ditautkan ke dalam tautan dalam jawaban ini. Saya ingin tahu di mana saya membaca hal lain itu? terima kasih banyak untuk menunjukkan itu, itu adalah asumsi yang salah saya senang untuk membuang. ive mengedit jawabannya.
mikeserv
versi terbaru dari tcshmemiliki ls-Fbuiltin yang mendukung LS_COLORScara yang sama seperti beberapa versi GNU ls, tetapi resor untuk memohon ls -Fjika Anda melewatkan opsi apa pun untuk itu, sehingga tidak akan berfungsi di sini kecuali jika lsGNU ada lsdi sistem Anda.
Stéphane Chazelas
-1

[Di Linux / Bash]

Saya akan melakukan ini:

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

The sedperintah runtuh beberapa ruang untuk satu ruang; yang cutekstrak bidang-9 dan seterusnya di mana bidang-pemisah adalah ruang.

Output khas dari ini:

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

Alternatifnya adalah:

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

Tapi itu tidak sempurna: yang pertama bisa menghasilkan ruang tambahan; yang kedua, ruang terdepan.

Rhubbarb
sumber
Pertanyaan itu secara eksplisit menyatakan "... tanpa harus menyalurkan melalui perintah lain ..."
Jeff Schaller
@JeffSchaller: Poin bagus; Saya setuju. Saya berharap, bahwa ini masih berguna bagi seseorang yang menginginkan jawaban untuk pertanyaan judul (tanpa detail dalam uraian).
Rhubbarb