Як я можу перерахувати файли, у яких не існує посилань?


10

У мене є великий каталог "myfiles", повний різних документів і не хочу змінювати його структуру.

Тому я створив (кілька) інших каталогів для кожного класу документів. Наприклад, у мене є каталог "images", який має посилання на кожен .jpgабо .cr2файл у каталозі "myfiles", а також інші описові файли для кожного символьного посилання (з тим самим іменем файлу) з описом та іншими метаданими. Символьні посилання в каталозі / images можуть мати інше ім'я від оригінального пов'язаного файлу.

Я намагаюся знайти найпростіший спосіб переконатися, що кожен файл зображень у каталозі "myfiles" має символьне посилання на каталог "images".

Дивіться приклад структури папки

/myfiles/a.doc
/myfiles/b.jpg
/myfiles/c.cr2
/myfiles/d.mov

має призвести

/images/b_800x600.jpg
/images/b_800x600.desc
/images/c_3820x5640.cr2
/images/c_3820x5640.cr2

Не повна відповідь, але ви можете зберегти результати find /myfiles -type fфайлу у файл, а потім скористайтеся find /images -type l -exec readlink {} \; | egrep myfilesдля отримання списку файлів, які позначені символом, /imagesпотім повторіть результати, роблячи sedпо кожному, щоб видалити шляхи в першому збереженому вами файлі, оскільки вони вже є мати символьне посилання, а залишені файли - це файли, у яких немає посилання.
Братчлі

2
Чи можливо ви замість цього використовувати жорсткі посилання, щоб ви могли використовувати лічильник жорстких посилань, щоб побачити, чи є у вас посилання? Використовуючи ls -lви можете бачити кількість твердих посилань у другому стовпці.
Ламберт

Робіть те, що говорить @Lambert. rmці символьні посилання і використовуйте, pax -rwl -s "\|.*regex|modifes_filename|" /path/to/myfiles/*.jpg /path/to/jpg_dirнаприклад, для отримання твердих посилань із програмно зміненими іменами лише тих файлів, які відповідають вашим jpgs. Ви можете отримати набагато більше, ніж із цього - наприклад, партії на основі часу зміни тощо
mikeserv

Відповіді:


6

Якщо я правильно підкреслив питання, потрібні файли у файлах myfiles, які не мають посилань на зображеннях:

#!/bin/bash

OIFS="$IFS"
IFS=$'\n'

files="$(find myfiles/ -type f -name '*.jpg' -or -name '*.cr2')"
for f in $files; do
    list="$(find -L images/ -xtype l -samefile "$f")"
    if [[ "$list" == "" ]]; then
        echo "$f does not have symlink."
    fi
done

IFS="$OIFS"

Існує застереження при такому підході, якщо ви маєте файл a.jpg у каталозі myfiles / 1 і у вас є посилання на цей файл у каталогах images / 3 або просто у зображеннях / файл не повідомлятиметься про відсутні сімпосилання.


Дякую ! Так, ти правильно зрозумів. Близький, але не зовсім. Моя вина не ваша :-) Приклад, який я наводив, показує простий каталог файлів myfiles. Насправді файли зображень під myfiles можуть знаходитися всередині будь-якого довільного рівня вкладених каталогів.
Роберт Олександр

Я відредагував відповідь, щоб шукати цілі файли, але перевірте, чи ви цього хочете.
taliezin

ТІЛЬКО там :-) Ваш скрипт ікочує, коли у файлах є пробіли (а може бути, і інші лайно, такі як одиночні апострофи "в них ...
Роберт Олександр

Я думаю, зараз має бути гаразд
taliezin

Ваша остання модифікація розділяє кожну f при виникненні кожної літери n! :-) Я прив’язав рядок IFS до IFS = тоді новий рядок з клавіатури, потім інший ". Тепер розкол, здається, працює, але я отримую довгу послідовність" missinglinks.sh: 11: missinglinks.sh: [[: не знайдено "
Роберт Олександр

3

Я припускаю, що файли під myfilesне символічними посиланнями, і що жодне з назв файлів не містить нових рядків. (Мій підхід все ще може працювати, якщо ці припущення порушені, але це ускладнюється.) Я також припускаю, що у вас є спільна readlinkутиліта, і вона підтримує -fканонізацію шляхів, що стосується Linux (і GNU, і BusyBox), але не наприклад, OSX.

Створіть список файлів і відсортуйте його на добру міру:

find /myfiles -type f -print | sort >all.list

Створіть список символічних цілей посилань з абсолютними шляхами.

find /images -type f -exec readlink -f {} \; | sort >linked.list

Перерахуйте файли, які не пов'язані:

comm -32 all.list linked.list

Якщо ви використовуєте оболонку, яка підтримує процес заміни, ви можете помістити все це в одну команду:

comm -23 <(find /myfiles -type f -print | sort) \
         <(find /images -type f -exec readlink -f {} \; | sort)

Якщо посилання під /imagesабсолютними, ви можете використовувати readlinkбез -fопції, яка доступна під * BSD та OSX.


Я збирався розмістити щось на кшталт вашої commкоманди, але я не буду тепер, коли бачу, що ви вже зробили це. Однак перенаправлення з sortсенсу не має сенсу; тоді процес заміни нічого не виведе. Крім того, ви можете додати багато каталогів поряд, /imagesякщо ви хочете знайти файли, до /myfilesяких не посилається жоден із ряду каталогів /images.
трійчатка

1
Дивіться stackoverflow.com/questions/7665/… про альтернативиreadlink -f
tripleee

@tripleee Я забув зняти перенаправлення, коли створив версію переспрямування процесу, дякую. Так, ви можете легко додавати інші каталоги або робити інші варіанти.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.