Як я можу знайти усі файли з жорсткою посиланням у файловій системі?


21

Мені потрібно знайти всі файли з твердим посиланням у заданій файловій системі. Наприклад, отримайте список файлів, кожен рядок містить зв'язані пари або трійки тощо.

Я розумію більш-менш, як це зробити, потрібно створити словник, введений в ключ inode для всіх файлів / каталогів файлової системи, виключити "." і ".." посилання, а потім індекси, що мають більше одного імені, є жорсткими посиланнями ... Але я сподіваюся, що, можливо, готове рішення існує, або хтось уже написав такий сценарій.

Відповіді:


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
Дякую, це не зовсім те, що я хотів, але досить близько. Я можу додати "% i", щоб надрукувати номери inode, а потім сортувати / згрупувати їх ...
haimg

15
Ви можете уникнути необхідності у awk, використовуючи синтаксис find "-links + n". Наприклад, знайти всі файли з принаймні двома посиланнями та роздрукувати необхідну інформацію:find / -type f -links +1 -printf '%i %n %p\n'
mbafford

як щодо трубопроводу через sort(+ uniq)? Мені було цікаво, тому я відправив його на свій основний комп'ютер (16 ГБ 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фактичні файли, як я вийняв їх для підрахунку входів.
північний Брадлі

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друкувати перше число викликів inode, а потім використовуючи опцію find'', -inumщоб показати всі файли, пов'язані з цим inode.


1
Ой! Це сканує файлову систему знову і знову для кожного твердопов'язаного файлу ...
haimg

1
Я не стверджував, що це швидко - і це начебто працює для малих дерев каталогів. Звичайно, належний індекс, який можна було б побудувати з, наприклад, результатів find . -type f -printf '%i %p\n', дозволив би побудувати набагато швидше рішення.
Клавдій

І це не обробляє простір у шляху AFAIK.
Жилль Кінот

Для forциклу, відповідно, буде коригувати IFS. Для розбору результатів команди find у моєму коментарі також повинно працювати все між першим пробілом та кінцем рядка як ім'я файлу.
Клавдій

1
@Sati: гарантує, що повідомлення про помилки відкидаються (наприклад, для папок, до яких ви не маєте доступу lost+foundтощо); що особливо важливо, якщо висновок слід обробляти далі, як у другому рядку.
DJCrashdummy

1

ІМХО найкращим способом є використання наступного рядка (обов'язково потрібно замінити /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

це сканує файлову систему лише один раз, показує inode, кількість жорстких посилань та шлях файлів з більш ніж одним твердим посиланням та сортує їх відповідно до inode.

якщо вас дратують повідомлення про помилки для папок, які вам заборонено читати, ви можете розширити рядок до цього:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.