ฉันจะสร้างรายการไฟล์ด้วยพา ธ สัมบูรณ์ใน Linux ได้อย่างไร


304

ฉันกำลังเขียนเชลล์สคริปต์ที่ใช้เส้นทางไฟล์เป็นอินพุต

ด้วยเหตุนี้ฉันต้องสร้างรายชื่อไฟล์แบบเรียกซ้ำพร้อมเส้นทางแบบเต็ม ตัวอย่างเช่นไฟล์barมีเส้นทาง:

/home/ken/foo/bar

แต่เท่าที่ฉันจะเห็นทั้งคู่lsและfindให้รายชื่อเส้นทางสัมพัทธ์เท่านั้น:

./foo/bar   (from the folder ken)

ดูเหมือนว่าเป็นข้อกำหนดที่ชัดเจน แต่ฉันไม่เห็นอะไรเลยในหน้าfindหรือlsหน้าคน

ฉันจะสร้างรายการไฟล์ในเชลล์รวมถึงพา ธ สัมบูรณ์ได้อย่างไร


ใช้:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
ผู้เรียน

คำตอบ:


305

หากคุณให้findพา ธ สัมบูรณ์เพื่อเริ่มต้นมันจะพิมพ์พา ธ สัมบูรณ์ ตัวอย่างเช่นเพื่อค้นหาไฟล์. htaccess ทั้งหมดในไดเรกทอรีปัจจุบัน:

find "$(pwd)" -name .htaccess

หรือถ้าเปลือกของคุณขยาย$PWDไปยังไดเรกทอรีปัจจุบัน:

find "$PWD" -name .htaccess

find เพียงเตรียมพา ธ ที่ได้รับไปยังพา ธ สัมพัทธ์กับไฟล์จากพา ธ นั้น

Greg Hewgillยังแนะนำให้ใช้pwd -Pถ้าคุณต้องการแก้ไข symlink ในไดเรกทอรีปัจจุบันของคุณ


9
โปรดทราบว่าถ้าคุณยังต้องการที่จะ symlinks pwd -Pแก้ปัญหาการใช้งาน
เกร็กฮิวกิล

5
สิ่งนี้มีประโยชน์ แต่ฉันคิดว่าการตอบสนองของผู้ใช้ 43,929 ด้านล่างมีความถูกต้องมากขึ้น: ls -d -1 $PWD/**/*แต่ฉันเดาว่ามันfind $PWDใช้ได้ (ทดสอบในการทุบตี)
Brian

9
@Brian ทำไม find $PWDเป็นเรื่องง่าย lsคาถามีความซับซ้อนและเทอะทะ (เว้นแต่คุณนามแฝงมัน) findไม่ได้ขึ้นอยู่กับการขยายตัวของเชลล์ glob ดังนั้นจะทำงานในเชลล์ใด ๆ findมีความยืดหยุ่นมากขึ้นฉันสามารถรับรายชื่อไฟล์ทั้งหมดซ้ำหรืออาจเป็นไดเรกทอรีทั้งหมดหรือบางทีฉันต้องการรายชื่อไฟล์ xml ทั้งหมดหรือไฟล์ทั้งหมดเปลี่ยนแปลงในสัปดาห์ที่ผ่านมา ทุกสิ่งที่เป็นไปได้ด้วยแต่ไม่ได้อย่างง่ายดายด้วยfind ls
Matthew Scharley

12
ฉันต้องใช้find "`pwd`" -name .htaccessเพราะช่องว่างในชื่อไดเรกทอรี
Paulo Casaretto

ฉันไม่เข้าใจคำสั่งนี้ไม่ให้เส้นทางที่แน่นอนของไฟล์ I ในขณะที่คำตอบอื่น ๆ ในรายการทำงาน
Bjørn Otto Vasbotten

202
readlink -f filename 

ให้เส้นทางที่สมบูรณ์แบบ แต่ถ้าไฟล์นั้นเป็น symlink คุณจะได้รับชื่อสุดท้ายที่ได้รับการแก้ไข


8
ดี ไม่ทำงานกับชุดตัวแปร readlink ของ BSD (เช่น Mac) ฉันใช้ gnucoreutils กับ mac และด้วยเหตุนี้จึงสามารถใช้ greadlink ซึ่งทำงานร่วมกับโซลูชันด้านบน
sheki

12
ไม่ใช้ Mac OS X
แอนดรูลาซารัส

1
@AndrewLazarus - สำหรับ Mac OS X ให้ใช้realpathแทน
cz

หากคุณติดตั้งเครื่องมือทุบตีผ่านทางbrew install coreutilsปฏิบัติการจะถูกติดตั้งเป็น/usr/local/opt/coreutils/libexec/gnubin/readlink
redolent

121

ใช้สิ่งนี้สำหรับ dirs ( /หลัง**จำเป็นในการทุบตีเพื่อ จำกัด ไว้ในไดเรกทอรี):

ls -d -1 "$PWD/"**/

สิ่งนี้สำหรับไฟล์และไดเรกทอรีโดยตรงภายใต้ไดเรกทอรีปัจจุบันที่มีชื่อประกอบด้วย.:

ls -d -1 "$PWD/"*.*

สำหรับทุกสิ่ง:

ls -d -1 "$PWD/"**/*

นำมาจากที่นี่ http://www.zsh.org/mla/users/2002/msg00033.html

ในทุบตี**เป็น recursive shopt -s globstarถ้าคุณเปิดใช้งาน


1
ls -d -1 $ PWD / ** / * ไม่สามารถเรียกคืนได้ หวังว่าฉันจะสามารถนำ +1 ของฉันกลับมา คุณสามารถทำ ** สำหรับแต่ละความลึกที่คุณต้องไปแม้ว่า
user606723

4
ตัวดำเนินการ ** เป็นตัวดำเนินการแบบวนซ้ำ หากคุณใช้คำสั่งในเชลล์ที่สนับสนุน (เช่น zsh) คำสั่งจะทำงานได้อย่างถูกต้อง
zebediah49

ls -d1 "$ PWD /"{*,.*} เพื่อจับไฟล์ที่ซ่อนอยู่ (จุด) สำหรับฉันเวอร์ชันเรียกซ้ำในคำตอบไม่ได้เตรียมเส้นทางสัมบูรณ์ไปยังไฟล์ในโฟลเดอร์ย่อย
Zael

ฉันคิดว่าฉันจะต้องใช้การค้นหา ... ฉันได้รับ -> bash: / bin / ls: รายการอาร์กิวเมนต์ยาวเกินไป
TelamonAegisthus

30

คุณสามารถใช้ได้

find $PWD 

ในทุบตี


3
ที่จะให้เส้นทางของไดเรกทอรีปัจจุบันและทุกไฟล์และไดเรกทอรีด้านล่างเช่นกัน นั่นอาจไม่ใช่สิ่งที่ผู้คนกำลังมองหา
เรียกเก็บเงิน

18
ls -d "$PWD/"*

สิ่งนี้มีลักษณะเฉพาะในไดเรกทอรีปัจจุบัน มันเสนอราคา "$ PWD" ในกรณีที่มีช่องว่าง


นี่ยังคงเป็นคำตอบที่ถูกต้อง แต่มันก็ดีที่จะรวมข้อมูลที่ไม่สามารถใช้ซ้ำได้ (ซึ่งเป็นสิ่งที่ฉันกำลังมองหาในความเป็นจริง!)
bbbco

1
สำหรับการใช้แบบเรียกซ้ำ: ค้นหา -exec ls -ld $ PWD / {} \;
ผู้เรียน

10

คำสั่ง: ls -1 -d "$PWD/"*

วิธีนี้จะให้เส้นทางแบบสัมบูรณ์ของไฟล์ดังนี้

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt

8

$PWDเป็นตัวเลือกที่ดีโดยแมทธิวกล่าวข้างต้น หากคุณต้องการค้นหาเฉพาะไฟล์ที่พิมพ์เท่านั้นคุณยังสามารถเพิ่มตัวเลือก -type f เพื่อค้นหาเฉพาะไฟล์ปกติ ตัวเลือกอื่น ๆ คือ "d" สำหรับไดเรกทอรีเท่านั้นเป็นต้นดังนั้นในกรณีของคุณมันจะเป็น (ถ้าฉันต้องการค้นหาเฉพาะไฟล์ที่มี. c ext):

find $PWD -type f -name "*.c" 

หรือถ้าคุณต้องการไฟล์ทั้งหมด:

find $PWD -type f

หมายเหตุ: คุณไม่สามารถสร้างชื่อแทนสำหรับคำสั่งดังกล่าวได้เนื่องจาก $ PWD ได้รับการกรอกข้อมูลอัตโนมัติไปยังไดเรกทอรีบ้านของคุณเมื่อตั้งชื่อแทนด้วย bash


ที่จริงแล้ว -d ไม่ได้หมายถึงเฉพาะไดเรกทอรีเท่านั้น - มันหมายถึงปฏิบัติต่อไดเรกทอรีเช่นไฟล์ ดังนั้นหากคุณ ls -d / home คุณจะได้รับ "/ home" ไม่ใช่รายการของสิ่งที่อยู่ใน / home
เทรวิส

@ Travis: เขากำลังพูดถึงตัวเลือกในการค้นหาไม่ใช่ ls ในกรณีของเขา "find / -type d" จะค้นหาเฉพาะไดเรกทอรี - ตามที่เขาพูด
oligofren

6

หากคุณให้พา ธ สัมบูรณ์คำสั่ง find คำสั่งนั้นจะคายผลลัพธ์ด้วยพา ธ สัมบูรณ์ ดังนั้นจากไดเรกทอรี Ken หากคุณต้องการพิมพ์:

find /home/ken/foo/ -name bar -print    

(แทนเส้นทางสัมพัทธ์find . -name bar -print)

คุณควรได้รับ:

/home/ken/foo/bar

ดังนั้นหากคุณต้องการls -lและให้มันคืนค่าพา ธ สัมบูรณ์คุณสามารถบอกคำสั่ง find เพื่อเรียกใช้งานls -lบนสิ่งที่พบ

find /home/ken/foo -name bar -exec ls -l {} ;\ 

หมายเหตุ: มีช่องว่างระหว่าง{}และ;

คุณจะได้รับสิ่งนี้:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

หากคุณไม่แน่ใจว่าไฟล์อยู่ที่ไหนคุณสามารถเปลี่ยนตำแหน่งการค้นหาได้ตลอดเวลา ตราบใดที่เส้นทางการค้นหาเริ่มต้นด้วย "/" คุณจะได้รับเส้นทางที่แน่นอนกลับมา หากคุณกำลังค้นหาสถานที่ (เช่น /) ที่คุณจะได้รับการปฏิเสธข้อผิดพลาดที่ได้รับอนุญาตจำนวนมากฉันขอแนะนำให้เปลี่ยนเส้นทางข้อผิดพลาดมาตรฐานเพื่อให้คุณสามารถเห็นผลลัพธ์การค้นหา:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

( 2>เป็นไวยากรณ์สำหรับเชลล์ Borne และ Bash แต่จะไม่ทำงานกับ C เชลล์มันอาจทำงานในเชลล์อื่นด้วยเช่นกัน แต่ฉันรู้แน่ ๆ ว่ามันทำงานใน Bourne และ Bash)


คุณสามารถส่งผ่าน args หลายเดียวกันกระบวนการที่มีls -exec ls -ld {} +(คุณอาจต้องการ-dไม่มีlsเนื้อหารายการไดเรกทอรี) หรือดีกว่าการใช้หาของในตัวด้วยls find ... name bar -lsนอกจากนี้คุณยังมีความผิดไวยากรณ์สำหรับหนึ่งหาเรื่องต่อคำสั่ง: {} \;คุณต้องพูดอัฒภาคจากเปลือกจึงเป็น
Peter Cordes

5

fd

ใช้fd(ทางเลือกfind) ใช้ไวยากรณ์ต่อไปนี้:

fd . foo -a

.รูปแบบการค้นหาอยู่ที่ไหนและfooเป็นไดเรกทอรีราก

เช่นเพื่อแสดงรายการไฟล์ทั้งหมดในetcแบบวนซ้ำให้เรียกใช้: fd . /etc -a.

-a, --absolute-path แสดงแน่นอนแทนทางญาติ


2

เพียงทางเลือกอื่นในการ

ls -d "$PWD/"* 

เพื่อระบุว่า*เป็นการขยายตัวของเชลล์ดังนั้น

echo "$PWD/"*

จะทำเช่นเดียวกัน (ข้อเสียเปรียบที่คุณไม่สามารถใช้-1เพื่อคั่นด้วยบรรทัดใหม่ไม่ใช่ช่องว่าง)


คุณอธิบายเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ไหม? การขยายตัวของเชลล์คืออะไร? วิธีใช้-1เพื่อคั่นด้วยบรรทัด?
Antonio Araujo

@Antonio Araujo ส่วนขยายของเชลล์คือเชลล์ (เช่น bash) จะแทนที่ * ด้วยรายการไฟล์ - สามารถอ่านเพิ่มเติมได้ที่หน้า bash man -1 คือตัวเลือกคำสั่ง ls, echo เป็นคำสั่งอื่น ๆ ไม่มีตัวเลือกเดียวกัน
Marisha


1

นี่คือตัวอย่างที่พิมพ์รายการโดยไม่มีระยะเวลาเพิ่มเติมและยังแสดงวิธีการค้นหาไฟล์ที่ตรงกัน หวังว่านี่จะช่วย:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"

1

สิ่งนี้ใช้ได้สำหรับฉัน แต่มันไม่ได้เรียงตามลำดับตัวอักษร

find "$(pwd)" -maxdepth 1

คำสั่งนี้แสดงรายการตามตัวอักษรรวมทั้งแสดงรายการไฟล์ที่ถูกซ่อนด้วย

ls -d -1 "$PWD/".*; ls -d -1 "$PWD/"*;


1

คุณอาจต้องการลองสิ่งนี้

for name in /home/ken/foo/bar/*
do
    echo $name
done

คุณจะได้รับเส้นทางเอบีเอสโดยใช้forห่วงและเพียงโดยไม่ต้องechofind


0

หากคุณต้องการรายชื่อของไฟล์ทั้งหมดในปัจจุบันเช่นเดียวกับไดเรกทอรีย่อย

find $PWD -type f

หากคุณต้องการรายการไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันเท่านั้น

find $PWD -maxdepth 1 -type f

0

สิ่งนี้จะให้เส้นทางแบบบัญญัติ (จะแก้ไข symlink): realpath FILENAME

หากคุณต้องการเส้นทางที่เป็นที่ยอมรับไปยัง symlink ตัวเองแล้ว: realpath -s FILENAME


0

ส่วนใหญ่ถ้าไม่ใช่วิธีการที่แนะนำทั้งหมดจะส่งผลให้เส้นทางที่ไม่สามารถใช้โดยตรงในคำสั่งเทอร์มินัลอื่น ๆ หากเส้นทางนั้นมีช่องว่าง โดยหลักการแล้วผลลัพธ์จะมีเครื่องหมายทับ สิ่งนี้ใช้ได้กับฉันใน macOS:

find / -iname "*SEARCH TERM spaces are okay*" -print 2>&1  | grep -v denied |grep -v permitted |sed -E 's/\ /\\ /g'

-1

find / -print จะทำเช่นนี้


1
... น่าเสียดายที่มันจะทำอย่างอื่น (เช่นการแสดงไฟล์อื่น ๆ 'บางส่วน' ยกเว้นว่ามีการกรอง)
DerMike

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