Я пытаюсь удалить все пустые папки в каталоге. Тем не менее, find . -type f -empty не находит ничего, потому что каждая папка содержит скрытую папку .svn .
Как я могу обойти это?
Я пытаюсь удалить все пустые папки в каталоге. Тем не менее, find . -type f -empty не находит ничего, потому что каждая папка содержит скрытую папку .svn .
Как я могу обойти это?
Незначительные изменения (просто распечатайте каталог и отправьте в xargs позже):
for folder in $(find -type d ! -path *.svn*); do
  if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
    echo $folder
  fi
done
Поместите это где-нибудь в ваш $PATH , возможно, как svn-empties а затем сначала запустите:
svn-empties
для просмотра списка найденных каталогов (при необходимости измените список) и затем направьте их в xargs:
svn-empties | xargs svn rm
Этот скрипт стал очень полезным для меня при использовании git-svn (спасибо!). Поскольку git не отслеживает пустые каталоги, я могу получить много пустых каталогов в хранилище Subversion. Я svn co отдельный экземпляр хранилища и запускаю svn-empties | xargs svn rm периодически. Использование Subversion в первую очередь не было моим решением;)
Я просто наткнулся на это, и я использовал этот скрипт, но изменил его, чтобы правильно рассматривать пустые каталоги только с .svn и без других файлов, скрытых или нормальных.
Кроме того, имейте в виду, что я использую svn rm, так что для работы с репозиторием вы можете адаптировать сценарий к работе в каталоге.
for folder in $(find -type d ! -path *.svn*); do
  if [ "`find $folder ! -path *.svn* ! -path $folder | wc -l`" -eq 0 ]; then
    svn rm $folder
  fi
done
Если вы можете, вы, конечно, можете сначала удалить все папки .svn . Недостаток: вы потеряете информацию контроля версий, если кто-то использует SVN. Если кто-то использует SVN, то не стоит просто удалять эти папки (или на самом деле вы должны удалить их и из SVN, так как SVN отслеживает папки и файлы).
Если это невозможно, я бы пошел со сценарием маршрута:
for folder in $(find . -type d); do
 if [ "`ls $folder | wc -l`" -eq 0 ]; then
  echo "I am going to delete $folder"
 fi
done
Сначала попробуйте пробный запуск, потому что может быть что-то удивительное. Тогда вы можете изменить rm -r вместо этого echo .
Однако обратите внимание, что это удалит все папки только с точечными файлами (поэтому, например, a/.this_is_super_important будет удален, если нет других файлов или папок).
svn-empties YOU_WANT_TO_SEARCH_PATH
C_IFS=$IFS
IFS=$'\n'
for folder in $(find "$1" -depth -type d ! -path *.svn*|sort -r); do
  counts=$(find "$folder" -type f ! -path *.svn* ! -path $folder | wc -l)
  if [ $counts -eq 0 ]; then
    echo $folder
  fi
done
IFS=$C_IFS
Чтобы избежать проблем с пробелами, find и магией IFS (имена файлов могут также содержать символы новой строки, поэтому IFS=$'\n' не является серебряной пулей), можно использовать глобусы и массивы. 
#!/bin/bash
search_dir=${1:-.}
shopt -s globstar dotglob
for svn_dir in "$search_dir"/**/.svn/; do
    base_dir=${svn_dir%/.svn/}
    base_dir_contents=("$base_dir"/*)
    if [ ${#base_dir_contents[@]} -eq 1 ]; then
        printf 'The directory "%s" only contains ".svn/".\n' "$base_dir"
    fi
done
globstar включает конструкцию обхода каталогов ** .dotglob включает в себя скрытые файлы в виде звездочек.for должен быть защищен от любых проблемных символов имени каталога. Глобусы всегда будут безопасно расширяться в Bash, что не относится к ls , find и т.д. Конечная косая черта гарантирует, что мы сопоставляем только папки с именами .svn а не обычные файлы (хотя в настоящем угловом случае)..svn , помещаются в массив. Если количество элементов в этом массиве равно 1 (то есть папка .svn которую мы по построению знаем * есть), то это то, что мы ищем.Он использует только встроенные модули Bash и, следовательно, должен быть быстрее, чем выдавать дополнительные системные вилки для find , но, скорее всего, разница не заметна, и в любом случае основным узким местом будет ввод / вывод.
*: Незначительный sidenote (также относится и к другим решениям): возможное состояние гонки, если, например, в каталоге есть только .svn и файл foo , а каталог .svn удаляется между аргументом for и массивом что также приведет к удалению foo . Однако, если кто-то со злым умыслом имеет право удалять файлы в файловой системе, игра, вероятно, уже потеряна, и их можно было бы удалить напрямую, чем с помощью временных атак.
Еще одно быстрое упоминание заключается в том, что другие ответы должны цитировать их расширения *.svn* . В противном случае команда find не будет выполнена, если текущая папка содержит файл, соответствующий этому глобанту:
$ mkdir foo && cd foo
$ mkdir -p test1/.svn test2
$ find -type d ! -path *.svn*
.
./test1
./test2
$ touch foo.svnbar
$ find -type d ! -path *.svn*
.
./test1
./test1/.svn
./test2
$ find -type d ! -path "*.svn*"
.
./test1
./test2
Без кавычек *.svn* будет преждевременно расширен оболочкой до foo.svnbar .