แสดงเฉพาะไฟล์ต้นทางและไฟล์ที่เชื่อมโยงเป้าหมายโดยใช้ `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 stat:

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ทำงานได้ดีมาก ขอบคุณ!
Chris Snow

1
บนระบบ RHEL6 เก่าสถิติเป็น GNU coreutils 8.4 stat -c %N -- /usr/local/bin/mvnและมีมันเป็น เพื่อลบใบเสนอราคาที่ฉันต้องไปนี้ใน| perl -pe 's/['"'"'`]//g'
cfi

@cfi tr -d \'\`จะเพียงพอ โปรดทราบว่าระบบ RHEL จะมี GNU findซึ่งคุณจะสามารถควบคุมได้มากขึ้น
Stéphane Chazelas

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 ~]$

นอกจากนี้โปรดไปอ่านผ่านหน้าคนของlsและตรวจสอบตัวเลือก-Lและ-Hและดูว่าจะพอเพียงความต้องการของคุณ


เจ๋งเรียนรู้สิ่งใหม่ทุกวัน
ปล้น

@Sree - ขอบคุณมาก! ฉันได้พยายามlsเลือก fileแต่ไม่ น่าเสียดายที่ดูเหมือนว่าจะไม่ทำงาน :(
Chris Snow

@SHC ขออภัยฉันคิดว่าคุณอยู่ในlinuxกล่อง โปรดเพิ่มosxเป็นหนึ่งในแท็กของคุณ ที่ควรได้รับความสนใจจากosxผู้ใช้เป็นอย่างดี ฉันได้แก้ไขโพสต์เพื่อเพิ่มแท็ก แต่ฉันมีเครดิตไม่เพียงพอที่การแก้ไขจะปรากฏทันที
Sree

@Sree - ไม่ต้องกังวลและขออภัยในความสับสน ฉันได้ยกระดับคำตอบของคุณไว้แล้วเพราะมันจะมีประโยชน์เมื่อฉันกลับไปที่เครื่องลินุกซ์
Chris Snow

อาจตรวจสอบอรรถประโยชน์ 'readlink' บน osx
tonioc

2

ด้วย GNU lsอย่างน้อยที่สุด(และแน่นอนว่า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ที่ยังอาจจะไม่ทำงานถ้าคุณทำบางอย่าง
Stéphane Chazelas

@StephaneChezales - นี้บ่งชี้อย่างน้อยว่ามันควรจะทำงานคล้ายกับ lsBSD ฉันจำได้ว่าอ่านว่าเมื่อเดือนที่แล้วประมาณlsว่ามีแนวโน้มที่จะยอมรับ termcap เช่นไวยากรณ์ จุดดีเกี่ยวกับln -s ///สิ่ง - แต่\0NULs ทำงานได้ดี - และ-Recursively ทำไม - ดีใช้งานง่าย ในบางกรณีง่ายกว่าfind- และดูเหมือนว่าจะเพิ่มเติมในหัวข้อที่นี่findเล็กน้อย ไม่ว่าในกรณีใด ๆ มีคนไม่มากนักที่จะพิจารณาดังนั้นฉันจึงพูดถึงมันเมื่อฉันเตือน
mikeserv

ดูman pageหรือที่นั่นสำหรับ FreeBSD หากคุณต้องการทดสอบสิ่งต่าง ๆ บน FreeBSD คุณสามารถใช้ซีดีสดเช่น GhostBSD / mfsbsd ใน VM
Stéphane Chazelas

@ StéphaneChazelas - ไม่ฉันไม่จำเป็นต้องทดสอบ - แน่นอนสัตว์ที่แตกต่างกันในเครือ หากคุณสนใจที่จะดูแหล่งที่มา gnu จะถูกเชื่อมโยงไปยังในลิงค์ในคำตอบนี้ ฉันสงสัยที่ฉันอ่านสิ่งอื่น ๆ ? ขอบคุณมากสำหรับการชี้ให้เห็นว่านั่นเป็นข้อสันนิษฐานที่เข้าใจผิดว่ายินดีทิ้ง ive แก้ไขคำตอบแล้ว
mikeserv

รุ่นล่าสุดของtcshมีls-Fในตัวที่รองรับLS_COLORSเช่นเดียวกับบางรุ่น GNU lsแต่มันรีสอร์ทอัญเชิญls -Fถ้าคุณผ่านตัวเลือกใด ๆ กับมันเพื่อที่จะไม่ทำงานที่นี่เว้นแต่lsเป็น GNU lsในระบบของคุณ
Stéphane Chazelas

-1

[บน Linux / Bash]

ฉันจะทำสิ่งนี้:

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

sedคำสั่งยุบช่องว่างหลายไปยังพื้นที่เดียว; cutสารสกัดจากสนามที่ 9 เป็นต้นไปที่สนามแยกเป็นพื้นที่

เอาท์พุททั่วไปจากนี้:

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

แต่สิ่งเหล่านี้ไม่สมบูรณ์: อันแรกสามารถส่งออกพื้นที่ต่อท้าย ช่องว่างที่สองนำหน้า


คำถามที่ระบุไว้อย่างชัดเจน "... โดยไม่ต้องผ่านท่อคำสั่งอื่น ..."
เจฟฟ์ Schaller

@JeffSchaller: จุดดี; ฉันเห็นด้วย. อย่างไรก็ตามฉันหวังว่านี่จะยังคงมีประโยชน์สำหรับคนที่ต้องการคำตอบสำหรับคำถามเรื่อง (โดยไม่มีรายละเอียดในคำอธิบาย)
Rhubbarb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.