Làm thế nào tôi có thể tìm thấy tất cả các tập tin liên kết cứng trên một hệ thống tập tin?


21

Tôi cần tìm tất cả các tập tin liên kết cứng trên một hệ thống tập tin nhất định. Ví dụ: lấy danh sách các tệp, mỗi dòng chứa các cặp được liên kết hoặc bộ ba, v.v.

Tôi hiểu ít nhiều về cách thực hiện, người ta cần tạo một từ điển được khóa bằng inode cho tất cả các tệp / thư mục trên một hệ thống tệp, loại trừ "." và các liên kết "..", và sau đó có nhiều hơn một tên là các liên kết cứng ... Nhưng tôi hy vọng rằng có thể có một giải pháp đã sẵn sàng hoặc ai đó đã viết một tập lệnh như vậy.

Câu trả lời:


17

Bạn có thể chạy lệnh sau:

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

để tìm tất cả các tập tin liên kết cứng.

Hoặc phiên bản @mbafford:

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

1
Cảm ơn, đây không phải là chính xác những gì tôi muốn, nhưng đủ gần. Tôi có thể thêm '% i' để in các số inode và sau đó sắp xếp / nhóm theo nó ...
haimg

15
Bạn có thể tránh sự cần thiết của awk bằng cách sử dụng cú pháp "-links + n 'của find. Ví dụ: để tìm tất cả các tệp có ít nhất hai liên kết và in ra thông tin cần thiết:find / -type f -links +1 -printf '%i %n %p\n'
mbafford 16/1/2015

làm thế nào về đường ống qua sort(+ uniq)? tôi đã tò mò vì vậy đã cho nó đi trên máy tính chính của tôi (16GB i5-2500k với ssd). với 2187757 tệp ( find / -xdev -type f | wc) mất 12 giây thực khi trả lại 3820 tệp / 570 inodes ( time sudo find / -xdev -type f -links +1 -printf "%i\n" | sort | uniq | wc). bạn sẽ cần bao gồm các %n %ptệp thực tế khi tôi lấy chúng ra để đếm các nút.
bắc-bradley

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

đưa ra một danh sách tất cả các tệp có nhiều hơn một liên kết, tức là các tệp tồn tại một liên kết cứng. Việc xử lý vấn đề này tương đối dễ dàng - một giải pháp khó khăn nếu bạn không có nhiều tệp như vậy

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

Nhưng tôi chân thành hy vọng rằng có những giải pháp tốt hơn, ví dụ bằng cách cho phép người đầu tiên findcon số in inode cuộc gọi và sau đó sử dụng find's -inumtuỳ chọn hiển thị tất cả các file liên quan đến inode này.


1
Ôi! Điều này quét hệ thống tập tin nhiều lần cho mỗi tập tin liên kết cứng ...
haimg

1
Tôi không khẳng định nó nhanh - và nó hoạt động cho các cây thư mục nhỏ. Tất nhiên, một chỉ mục thích hợp, có thể được xây dựng từ, ví dụ, đầu ra của find . -type f -printf '%i %p\n', sẽ cho phép một người xây dựng một giải pháp nhanh hơn nhiều.
Claudius

Và điều đó không xử lý không gian trong đường dẫn AFAIK.
Gilles Quenot

Đối với forvòng lặp, điều chỉnh IFS phù hợp sẽ hoạt động. Để phân tích đầu ra của lệnh find trong nhận xét của tôi, khai báo mọi thứ giữa khoảng trắng đầu tiên và cuối dòng là tên tệp cũng hoạt động.
Claudius

1
@Sati: nó đảm bảo rằng các thông báo lỗi sẽ bị loại bỏ (ví dụ: đối với các thư mục bạn không có quyền truy cập, lost+foundv.v.); Điều này đặc biệt quan trọng, nếu đầu ra nên được xử lý thêm như trong dòng thứ hai.
DJCrashdummy

1

IMHO cách tốt nhất là sử dụng dòng sau (chắc chắn bạn phải thay thế /PATH/FOR/SEARCH/bằng bất cứ thứ gì bạn muốn tìm kiếm):

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

điều này chỉ quét hệ thống tập tin một lần, hiển thị inode, số lượng liên kết cứng và đường dẫn của các tệp có nhiều hơn một liên kết cứng và sắp xếp chúng theo inode.

nếu bạn thấy khó chịu bởi các thông báo lỗi cho các thư mục bạn không được phép đọc, bạn có thể mở rộng dòng này sang đây:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.