У меня есть список файлов, которые я хочу проверить, существуют ли они в моей файловой системе. Я думал сделать это, используя find
в:
for f in $(cat file_list); do
find . -name $f > /dev/null || print $f
done
(используя zsh
), но это не работает, так как find
кажется, что он завершает работу , 0
независимо от того, находит ли он файл. Я предполагаю , что я мог бы передать его через какой - то другой тест , который проверяет , чтобы увидеть , если find
производит какой - либо выход (нефть , но эффективным было бы заменить > /dev/null
с |grep ''
) , но это чувствует , как с помощью тролля поймать козу (другие национальности могли бы сказать что - то о кувалды и грецкие орехи ).
Есть ли способ заставить find
меня дать полезное значение выхода? Или хотя бы получить список тех файлов, которые не были найдены? (Я могу себе представить, что последнее может быть легче благодаря некоторому хитрому выбору логических связок, но я, кажется, всегда завязываю в узлах, когда пытаюсь это выяснить.)
Предыстория / Мотивация: у меня есть «основная» резервная копия, и я хочу проверить, что некоторые файлы на моем локальном компьютере существуют на моей главной резервной копии, прежде чем удалять их (чтобы освободить место). Поэтому я составил список файлов, ssh
отредактировал их на главном компьютере, а потом не мог найти лучший способ найти пропавшие файлы.
locate
.locate
не показывает текущее состояние файловой системы, это может быть день или даже неделя. Это подходит в качестве базы для тестирования резервных копий.Ответы:
find
считает поиск ничего особенного случая успеха (ошибки не произошло). Общий способ проверить, соответствуют ли файлы некоторымfind
критериям, состоит в том, чтобы проверить, является ли выводfind
пустым. Для повышения эффективности, когда есть совпадающие файлы, используйте-quit
в GNU find, чтобы он завершал работу при первом совпадении, илиhead
(head -c 1
если доступно, в противном случае,head -n 1
что является стандартным) в других системах, чтобы заставить его умереть от разорванного канала, а не производить длинный вывод.В bash ≥4 или zsh вам не нужна внешняя
find
команда для простого сопоставления имен: вы можете использовать**/$name
. Bash версия:Zsh версия по схожему принципу:
Или вот более короткий, но более загадочный способ проверки существования файла, соответствующего шаблону. Спецификатор glob
N
делает вывод пустым, если совпадений нет,[1]
сохраняет только первое совпадение иe:REPLY=true:
меняет каждое совпадение, чтобы расширять1
вместо сопоставленного имени файла. Так**/"$name"(Ne:REPLY=true:[1]) false
расширяется,true false
если есть совпадение, или просто,false
если нет совпадения.Было бы эффективнее объединить все ваши имена в один поиск. Если количество шаблонов не слишком велико для ограничения длины вашей системы в командной строке, вы можете объединить все имена с помощью
-o
, сделать одинfind
вызов и постобработать вывод. Если ни одно из имен не содержит метасимволов оболочки (так что имена также являютсяfind
шаблонами), вот способ постобработки с использованием awk (не проверено):Другой подход заключается в использовании Perl и
File::Find
, что упрощает запуск кода Perl для всех файлов в каталоге.Альтернативный подход заключается в создании списка имен файлов с обеих сторон и работе над сравнением текста. Zsh версия:
источник
zsh
решение с**
синтаксисом. Это очень простое решение, и, хотя оно может быть не самым эффективным с точки зрения машины , оно, вероятно, самое эффективное с моей точки зрения, когда я его запоминаю! Кроме того, первое решение здесь отвечает на реальный вопрос в том, что оноfind
превращается во что-то, где код выхода отличает «Я получил совпадение» от «Я не получил совпадение».Вы можете использовать,stat
чтобы определить, существует ли файл в файловой системе.Вы должны использовать встроенные функции оболочки, чтобы проверить, существуют ли файлы.
«Тест» является необязательным, и скрипт фактически будет работать без него, но я оставил его там для удобства чтения.
Редактировать: Если у вас действительно нет выбора, кроме как работать со списком имен файлов без путей, я предлагаю вам создать список файлов один раз с помощью команды find, а затем выполнить итерацию по нему с помощью grep, чтобы выяснить, какие файлы там есть.
Обратите внимание, что:
источник
Первый, упрощенный подход, может быть:
а) сортировать свой список файлов:
чтобы найти пропуски, или
найти совпадения
Недостатки:
find может искать несколько файлов одновременно с некоторой подготовкой:
find -name a.file -или -name -b.file -или -name c.file ...
Может быть найти вариант? Опять же, предварительный список файлов предполагается:
Поиск по foo.bar не будет соответствовать ни файлу foo.ba, ни oo.bar с конструкцией --regexp (не должен быть подтвержден регулярным выражением без p).
Вы можете указать конкретную базу данных для поиска, и вам необходимо обновить ее перед поиском, если вам нужны последние результаты.
источник
Я думаю, что это тоже может быть полезно.
Это однострочное решение, в случае если вы выбираете в качестве «списка» реальные файлы, которые вы хотите синхронизировать с другой папкой:
чтобы помочь чтению:
этот пример исключает резервные файлы "* ~" и ограничивает обычный тип файла "-type f"
источник
Может быть?
источник
Почему бы просто не сравнить длину списка запросов с длиной списка результатов?
источник