Использование псевдонима команды, включающей awk

POSIX sh + найти

Вот решение, основанное только на POSIX find и POSIX sh. Перечислите все каталоги, затем отфильтруйте те, которые содержат только запись с именем .DS_Store.

find -type d -exec sh -c '
    cd "$0" &&
    for x in *.[!.]*..?*; do
      if [ "$x" = ".DS_Store" ]; then continue; fi;
      if [ -e "$x" ] || [ -L "$x" ]; then exit 1; fi;
    done' {} \; -print
  • Я использую findдля рекурсивного перечисления всех каталогов.
  • В каждом каталоге я вызываю shдля запуска кода оболочки.
  • Цикл forперебирает все файлы в каталоге.
  • Тело цикла пропускается .DS_Store.
  • Каждый из трех шаблонов остается неизменным, если он не соответствует ни одному файлу. [ -e "$x" ] || [ -L "$x" ]захватывает любой файл, включая битые символические ссылки; единственный способ, которым они не совпадают, - это если шаблон остался неизменным.
  • Поэтому фрагмент оболочки запускается exit 1, если есть файл, отличный от .DS_Store,и возвращает 0 в случае успеха в противном случае.
  • Измените -printна -exec …, если вы хотите сделать что-то другое, кроме печати имен.

Зш

Вот решение в zsh. Измените echoна любую команду, которую вы хотите запустить.

setopt extended_glob
echo **/*(/DNe\''a=($REPLY/^.DS_Store(DNY1)); ((!#a))'\')
  • **/*рекурсивно перечисляет все файлы.
  • С квалификатором glob /, **/*(/)рекурсивно перечисляет все каталоги.
  • Квалификатор glob Nгарантирует, что вы получите пустой список, если нет совпадений (по умолчанию zsh сигнализирует об ошибке ).
  • Квалификатор glob Dприводит к включению точечных файлов.
  • Квалификатор glob e\''CODE'\'запускает CODEдля каждого совпадающего имени файла и ограничивает совпадения теми, для которых CODEуспешно. CODEможет использовать переменную $REPLYдля ссылки на имя файла.
  • ^.DS_Storeсоответствует файлам, которые не называются .DS_Store.
  • Таким образом, КОД ограничивает совпадения теми, для которых количество файлов, отличных от .DS_Store, равно нулю.
  • Квалификатор glob Y1ограничивает совпадения до одного (это всего лишь повышение эффективности ).

Питон

Вот решение на Python (оно работает как на 2, так и на 3 ). Структура более четкая, несмотря на то, что она сжата в один -вкладыш.

python -c 'import os; print("\n".join([path for path, dirs, files in os.walk(".") if dirs == [] and files in ([], [".DS_Store"])]))'
  • os.walkрекурсивно возвращает список каталогов по своему аргументу. Для каждого каталога создается тройка, содержащаяpath(путь к каталогу ),dirs(список подкаталогов )иfiles(список файлов в каталоге, которые сами по себе не являются каталогами ). ].
  • [… for … in os.walk(…) if …]фильтрует результат os.walk.
  • Предложение ifсохраняет элемент, только если он не имеет подкаталогов и файлов, отличных от .DS_Store.
  • Скрипт печатает принятые элементы,соединены с новой строкой между ними и с последней новой строкой.
0
24.10.2020, 18:28
0 ответов

Теги

Похожие вопросы