Как мне найти find, следуя большинству, но не всем, символическим ссылкам?

10

Моя ОС и домашний каталог находятся на SSD. Я храню несколько больших файлов на жестком диске и символическую ссылку из моего домашнего каталога на жесткий диск (например, ~ / Videos / Films - это символическая ссылка на / mnt / hdd / Films). У меня также есть несколько префиксов Wine, каждый из которых имеет dosdevices / z: символическую ссылку на /.

Так что, если я использовал find без -L, он пропустит все, что находится на жестком диске. Но если я использую find с -L, он заканчивается циклом из-за символической ссылки Wine на /.

Есть ли разумный способ решить эту проблему, чтобы найти поиск там, где я хочу? Интуитивно, я хочу что-то вроде «следовать символическим ссылкам, если они не находятся в каталоге под названием dosdevices». «Перейдите по символическим ссылкам, которые находятся на жестком диске» тоже будет работать.

Марк Раймонд
источник

Ответы:

11

-pruneПервичного говорит findне Recurse в директории.

find -L -path ~/.wine/dosdevices -prune -o -type f -name 'My Favorite Movie.*' -print

Если вы хотите использовать -lnameв своем состоянии, вы не можете использовать эту -Lопцию, потому что -Lзаставляет большинство предикатов воздействовать на цель ссылки, в том числе -lname. В этом случае я бы рекомендовал использовать как домашний каталог, так и корневой каталог жесткого диска в качестве корней поиска.

find ~ /mnt/hdd -xtype f -name 'My Favorite Movie.*'

Вы можете запустить, find ~ -type l …чтобы собрать список символических ссылок и использовать их в качестве дополнительных корней.

( IFS=$'\n'; set -f;
  find ~ $(find ~ -type l -lname '/mnt/hdd/*') \
       -xtype f -name 'My Favorite Movie.*' )

Если вы действительно хотите использовать рекурсив по символическим ссылкам, вы можете исключить определенные символические ссылки по цели, а не по имени. Однако вы можете исключить только конечный список, но не шаблон или поддерево.

find -L \( -samefile /exclude/this -o -samefile ~/and/that \) -prune -o \
     -type f -name 'My Favorite Movie.*' -print

Вы можете использовать другие критерии, такие как ! -writable(файлы, на которые у вас нет разрешения на запись), но я не думаю, что GNU find может рекурсировать по символическим ссылкам, только если их целевой текст соответствует определенному выражению.

Вы можете создать findкоманду, которая делает почти то, что вы хотите, за исключением того, что не исключаете достаточное количество символических ссылок, запустите find2perl, чтобы преобразовать запрос в скрипт Perl, и немного подправьте скрипт Perl. Однако многие переключатели GNU обнаруживают, что find2perl не распознает.

Жиль "ТАК - перестань быть злым"
источник
Спасибо! -pruneэто просто то, что я искал. Я обнаружил, что в нем find ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype dперечислены все символические ссылки, по которым я не хочу следовать; Сейчас я пытаюсь найти способ использовать этот запрос для сокращения.
Марк Раймонд
@MarkRaymond Общий принцип find ~ <negative criteria> -prune -o <positive criteria> -print, такfind ~ \( -lname ~ -o -lname ~/\* -o -lname / \) -xtype d -prune -o <whatever it is you want> -print
Жиля SO- перестать быть злом »
@Giles - это прекрасно работает без -L, но как только я добавлю -L, выражения -lname больше не будут работать (так как страница руководства говорит, что они не будут). Так что, в принципе, мне нужны некоторые условия, чтобы следовать символическим ссылкам, а другие - нет!
Марк Раймонд
Я не могу придумать способ сделать именно то, что вы хотите с помощью find. Смотрите мое редактирование для некоторых приближений.
Жиль "ТАК - перестань быть злым"
1

Для поиска ВСЕХ ссылок, это работало для меня:

find -L . -name \*.txt
Джим
источник
0

Сколько символических ссылок на жесткие диски у вас есть? Если это не слишком много, одним из решений является не использовать «-L» при явном указании символических ссылок, которым вы хотите следовать в командной строке поиска. Что-то типа:

find .  ~/Videos/Films -name '*file I want*' ...

Это будет искать текущий каталог ("."), А также символическую ссылку "~ / Videos / Films", но не будет переходить в другие символические ссылки.

John1024
источник
0

Другое решение, которое позволяет обойти эту проблему (по крайней мере, в моем случае), заключается в использовании bind mounts вместо символических ссылок для каталогов на жестком диске. Это делается путем добавления записей в /etc/fstabследующем виде:

/mnt/hdd/Films /home/mark/Videos/Films none bind 0 0

Марк Раймонд
источник