Intereting Posts
Почему команда «hwclock» применяет положительное смещение для местного времени, тогда как команда «date» применяет отрицательное смещение? Выполнение потенциально вредной программы на Linux Как установить значение для mteHotContextName при использовании процесса мониторинга в SNMP Преобразование цветного вывода в html Как использовать systemd hybrid-sleep вместо приостановки под GNOME в Linux? Кто-нибудь получил привязки Android NDK для запуска на ARM вместо x86 или x86_64? Правила rsync только для синхронизации конкретных субдиров в длинных путях Как запустить это в sudo? Как я могу повлиять на отображение виртуального дисплея (X Server) после загрузки? Как использовать библиотеки, установленные nix во время выполнения? bash: используйте переменную для хранения stderr | stdout redirection Как удалить несколько столбцов в файле на основе информации во втором файле? Получение Mint MATE (Marco?), Чтобы поместить окно-закрыть X в фактический угол, а не только рядом с ним Как выполнить chroot с пространствами имен Linux? Как удалить строку, если строка является единственной вещью на линии

Рекурсивно перечислить все каталоги, содержащие один или несколько файлов изображений jpg

Я пытаюсь привести в порядок мои фотографии, которые по разным историческим причинам разбросаны по всей моей системе. Чтобы я мог начать работу над этой задачей, я пытался использовать командную строку для создания списка всех каталогов, содержащих один или несколько файлов jpg. Я уверен, что мне не нужно беспокоиться о поиске других форматов файлов изображений, но мне нужно разрешить появление jpg в верхнем и нижнем регистре.

Я хотел бы, чтобы каждое имя каталога отображалось только один раз в конечном списке. Чтобы привести пример, если у меня есть следующие каталоги, каждый из которых содержит один или несколько файлов JPG или JPG ….

~Mike/Pictures ~Mike/Pictures/London/Olympics ~Mike/Pictures/London ~Mike/Pictures/London/Holiday ~Mike/Photos ~Mike/Family History/Swaine 

Я хотел бы, чтобы результаты отображались в каждом каталоге, указанном только один раз – независимо от количества файлов изображений, которые могут содержать, – предпочтительно отсортированы, а затем записаны в файл

 ~Mike/Family History/Swaine ~Mike/Photos ~Mike/Pictures ~Mike/Pictures/London ~Mike/Pictures/London/Holiday ~Mike/Pictures/London/Olympics 

Мои навыки командной строки просто не до этого! Я могу использовать множество простых форм одиночных команд, но как только они становятся сложными и / или должны быть связаны с каналами, все имеет тенденцию идти не так.

Предполагая, что файлы изображений JPEG имеют суффикс .jpg :

 find "$HOME" -type f -name '*.jpg' \ -exec sh -c 'for d; do dirname "$d"; done' sh {} + | sort -u -o jpeg_dirs.txt 

Это зависит от того, что у вас нет фанковых имен каталогов с новыми символами в их именах.

С GNU find :

 find "$HOME" -type f -name '*.jpg' -printf '%h\n' | sort -u -o jpeg_dirs.txt 

Эти команды find найдут все изображения JPEG в вашем домашнем каталоге и распечатают имена каталогов, где они были найдены. sort -u примет этот список имен каталогов, сортирует его и удаляет дубликаты. Результат будет записан в файл jpeg_dirs.txt в текущем каталоге.

Простым способом является перечислить все файлы .jpg , а затем отменить базовые имена файлов (часть после последней косой черты) и удалить дубликаты. Вы можете использовать sed для разделения части каждой строки после последней косой черты. Есть команда удалить дубликаты, которые называются uniq , но он предполагает сортировку ввода; если вам все равно нужно сортировать, вы можете позволить sort выполнить уникальность.

 find ~Mike -iname '*.jpg' | sed 's!/[^/]*$!!' | sort -u >directories_with_jpeg_files.txt 

Это предполагает, что ни один из каталогов или файлов не имеет новую строку в их имени. Имена файлов с символами новой строки не отображаются в обычных обстоятельствах, но будьте осторожны, если имена файлов могут быть выбраны враждебным лицом (например, если вы обрабатываете файлы, которые были загружены на сервер, и загрузчик может выбрать имя файла) ,

Если есть каталоги, содержащие много файлов JPEG и не много каталогов, не содержащих JPEG-файл, этот метод тратит много времени на отчетность, а затем избыточные файлы. Невозможно сказать, что найти ярлык каталога, как только он что-то нашел в нем. Но вы можете ограничить поиск в каталогах и рассказать ему искать файл JPEG в каждом каталоге. Это увеличивает стоимость каталогов, которые не содержат файлы JPEG, однако, при наличии большого количества каталогов JPEGless может иметь низкую производительность.

 find ~Mike -type d -exec sh -c ' for d do set -- "$d/*.[Jj][Pp][Gg]"; if [ -e "$1" ]; then printf %s\\n "$d"; fi done ' sh {} + | sort -u >directories_with_jpeg_files.txt 

В качестве альтернативы, в zsh, вы можете использовать подстановочный знак ** для рекурсивного перемещения каталогов (#i) чтобы совпадение со следующим компонентом пути не учитывалось, чтобы сделать шаблон **/(#i)*.jpg matching *.jpg и *.JPG.Jpg и т. Д.) В целом дереве каталогов. Добавьте модификатор истории h в квалификатор glob, чтобы извлечь часть каталога. Поместите это в переменную массива dirs=(…) и извлеките уникальные элементы этого массива с помощью флага расширения параметра u .

 set -o extendedglob # for (#i); best in ~/.zshrc dirs=(~Mike/**/(#i)*.jpg(:h)) print -lr -- ${(u)dirs} >directories_with_jpeg_files.txt 

Эквивалент метода check-per-directory выше – использовать квалификатор e glob.

 print -lr ~Mike/**/*(/e\''set -- $REPLY/*.(#i)jpg(N[1]); (($# != 0))'\') >directories_with_jpeg_files.txt 
 find . -iname '*.jpg' -execdir sh -c 'pwd' _ {} + | sort -u > dirs_with_jpegs.txt 

Должно работать достаточно хорошо, предполагая, что ваша реализация find поддерживает -execdir (это, вероятно, делает). -execdir выполняет команду в каталоге, где находится найденный файл. В этом случае мы выполняем команду pwd , которая печатает имя каталога. Мы завершаем команду sh -c чтобы разделить аргументы. (Некоторые (все?) Реализации find требуют замены {} аргумента, которая будет списком jpeg-файлов в текущем каталоге. Мы хотим игнорировать этот список и печатать только каталог.)