ฉันจะหาไฟล์ hardlinked ทั้งหมดบนระบบไฟล์ได้อย่างไร?


21

ฉันต้องการค้นหาไฟล์ hardlinked ทั้งหมดในระบบไฟล์ที่กำหนด เช่นรับรายการไฟล์แต่ละบรรทัดมีคู่ที่เชื่อมโยงหรือแฝดสามเป็นต้น

ฉันเข้าใจวิธีการทำมากขึ้นหรือน้อยลงเราต้องสร้างพจนานุกรมที่คีย์โดยไอโหนดสำหรับไฟล์ / ไดเรกทอรีทั้งหมดในระบบไฟล์ยกเว้น "." และลิงก์ ".. " จากนั้น indodes ที่มีชื่อมากกว่าหนึ่งชื่อคือฮาร์ดลิงก์ ... แต่ฉันหวังว่าอาจมีโซลูชันสำเร็จรูปอยู่หรือมีคนเขียนสคริปต์เช่นนั้นแล้ว

คำตอบ:


17

คุณสามารถเรียกใช้คำสั่งต่อไปนี้:

find / -type f -printf '%n %p\n' | awk '$1 > 1{$1="";print}'

เพื่อค้นหาไฟล์ที่เชื่อมโยงทั้งหมด

หรือเวอร์ชัน @mbafford:

find / -type f -links +1 -printf '%i %n %p\n'

1
ขอบคุณนี่ไม่ใช่สิ่งที่ฉันต้องการ แต่ใกล้พอ ฉันสามารถเพิ่ม '% ฉัน' ที่จะพิมพ์ตัวเลข inode แล้วเรียง / กลุ่มโดยมัน ...
haimg

15
คุณสามารถหลีกเลี่ยงความจำเป็นในการ awk โดยใช้ไวยากรณ์ "-links + n 'ของ find เช่นเพื่อค้นหาไฟล์ทั้งหมดที่มีลิงค์อย่างน้อยสองลิงก์และพิมพ์ข้อมูลที่จำเป็น:find / -type f -links +1 -printf '%i %n %p\n'
mbafford

แล้วท่อผ่านsort(+ uniq) ล่ะ? ฉันอยากรู้อยากเห็นจึงให้มันไปบนคอมพิวเตอร์หลักของฉัน (16GB i5-2500k กับ ssd) ด้วย 2187757 ไฟล์ ( find / -xdev -type f | wc) ใช้เวลา 12 วินาทีจริงเมื่อส่งคืนไฟล์ 3820/570 inodes ( time sudo find / -xdev -type f -links +1 -printf "%i\n" | sort | uniq | wc) คุณจะต้องรวมถึง%n %pไฟล์จริงตามที่ฉันเอาออกมาเพื่อนับไอโหนด
north-bradley

17
find . -type f -links +1 2>/dev/null

ให้รายชื่อไฟล์ทั้งหมดที่มีมากกว่าหนึ่งลิงค์คือไฟล์ที่มีฮาร์ดลิงก์ การวนซ้ำนั้นค่อนข้างง่าย - โซลูชันแฮ็คถ้าคุณไม่มีไฟล์จำนวนมาก

for i in $(find . -type f -links +1 2>/dev/null); do find -samefile $i | awk '{printf "%s ", $1}'; printf "\n"; done | sort | uniq

แต่ผมหวังเป็นอย่างยิ่งว่าจะมีการแก้ปัญหาที่ดีกว่าเช่นโดยการปล่อยให้คนแรกที่findโทรพิมพ์หมายเลขไอโหนดแล้วใช้findของ-inumตัวเลือกที่จะแสดงไฟล์ทั้งหมดที่เกี่ยวข้องกับไอโหนดนี้


1
อุ๊ย! นี่จะสแกนระบบไฟล์ซ้ำแล้วซ้ำอีกสำหรับไฟล์ hardlinked แต่ละไฟล์ ...
haimg

1
ฉันไม่ได้อ้างว่ามันเร็ว - และมันเรียงลำดับของงานสำหรับไดเรกทอรีต้นไม้ขนาดเล็ก แน่นอนว่าดัชนีที่เหมาะสมซึ่งสามารถสร้างขึ้นได้จากตัวอย่างเช่นผลลัพธ์ของfind . -type f -printf '%i %p\n'จะช่วยให้หนึ่งสร้างโซลูชันที่เร็วขึ้นมาก
Claudius

และนั่นไม่ได้จัดการพื้นที่ในเส้นทาง AFAIK
Gilles Quenot

สำหรับการforวนซ้ำการปรับ IFS ตามนั้นจะทำงานได้ ในการแยกเอาต์พุตของคำสั่ง find ในความคิดเห็นของฉันการประกาศทุกสิ่งระหว่างช่องว่างแรกและจุดสิ้นสุดของบรรทัดเพื่อให้ชื่อไฟล์ควรใช้เช่นกัน
Claudius

1
@Sati: ช่วยให้มั่นใจได้ว่าข้อความแสดงข้อผิดพลาดถูกทิ้ง (เช่นสำหรับโฟลเดอร์ที่คุณไม่ได้เข้าถึงlost+foundเป็นต้น); ซึ่งเป็นสิ่งสำคัญโดยเฉพาะอย่างยิ่งหากการประมวลผลควรดำเนินการเพิ่มเติมเช่นในบรรทัดที่สอง
DJCrashdummy

1

IMHO วิธีที่ดีที่สุดคือใช้บรรทัดต่อไปนี้ (แน่นอนว่าคุณต้องแทนที่/PATH/FOR/SEARCH/ด้วยสิ่งที่คุณต้องการค้นหา):

find /PATH/FOR/SEARCH/ -xdev -printf '%i\t%n\t%p\n' | fgrep -f <(find . -xdev -printf '%i\n' | sort -n | uniq -d) | sort -n

สิ่งนี้จะสแกนระบบไฟล์เพียงครั้งเดียวแสดงไอโหนดจำนวนฮาร์ดลิงก์และพา ธ ของไฟล์ที่มีฮาร์ดลิงก์มากกว่าหนึ่งและเรียงลำดับตามไอโหนด

หากคุณรำคาญกับข้อความแสดงข้อผิดพลาดสำหรับโฟลเดอร์ที่คุณไม่ได้รับอนุญาตให้อ่านคุณสามารถขยายบรรทัดเป็น:

find /PATH/FOR/SEARCH/ -xdev -printf '%i\t%n\t%p\n' 2> /dev/null | fgrep -f <(find . -xdev -printf '%i\n' 2> /dev/null | sort -n | uniq -d) | sort -n
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.