.svn 폴더가있는 경우에도 빈 폴더를 모두 삭제하십시오. 디렉토리 내의 모든 빈

디렉토리 내의 모든 빈 폴더를 삭제하려고합니다. 그러나 find . -type f -empty모든 폴더에 숨겨진 .svn폴더 가 있으므로 아무것도 찾지 않습니다 .

이 문제를 어떻게 해결할 수 있습니까?



답변

가능하면 먼저 모든 .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다른 파일이나 폴더가없는 경우 삭제됨).


답변

사소한 수정 (단순히 디렉토리와 파이프를 인쇄하십시오 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


답변

공백 findIFS마술 (파일 이름에는 실제로 줄 바꿈이 포함될 수 있으므로 IFS=$'\n'은색 글 머리 기호가 아님) 과 같은 문제를 피하기 위해 glob 및 배열을 사용할 수 있습니다.

#!/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글로브는 문제가 디렉토리 이름 문자에 대한 안전합니다. globs와는 것입니다 항상 의 경우와하지 않은, 배쉬 안전하게 확장 ls, find후행 슬래시 우리는 일치 확인합니다, 등의 폴더 이름 .svn이 아닌 일반 파일 (비록 실제 코너 케이스).
  • .svn디렉토리가 일치하는 폴더에 포함 된 파일 이름이 배열로 붙습니다. 이 배열의 항목 수가 1 인 경우 (즉, .svn구성에 의해 우리가 알고 있는 폴더가 * 있음) 우리가 찾는 것입니다.

Bash 내장 기능 만 사용하므로 추가 시스템 포크를 발행하는 것보다 빠르지 find만 차이점은 눈에 띄지 않으며 I / O는 주요 병목 현상이 될 것입니다.


* 만이 예되면 잠재적 인 경쟁 상태가 마이너 (!) 참고은 (물론 다른 솔루션 적용) .svnfoo디렉토리의 파일과 .svn디렉토리 사이 제거 for하고 초래 배열 글로브 foo제거되고 게다가. 그러나 악의적 인 의도를 가진 사람이 파일 시스템에서 파일을 제거 할 권한이있는 경우 게임이 이미 손실 된 것이므로 타이밍 공격보다 직접 쉽게 제거 할 수 있습니다.


또 다른 빠른 언급은 다른 답변이 *.svn*확장을 인용해야한다는 것 입니다. 그렇지 않으면 find현재 폴더에 해당 glob와 일치하는 파일이 포함되어 있으면 명령이 실패합니다.

$ 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.


답변

  1. 경로에서 공백 문제를 해결했습니다.
  2. 다음과 같이 PATH 매개 변수를 사용하여 스크립트를 호출 할 수 있습니다.

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


답변