디렉토리 내의 모든 빈 폴더를 삭제하려고합니다. 그러나 find . -type f -empty
모든 폴더에 숨겨진 .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을 처음 사용하는 것은 내 결정이 아니 었습니다.)
git-svn
에는 사용할 수 --rmdir
의 옵션을 git svn dcommit
. 디렉토리가 비면 바로 svn에서 디렉토리를 제거합니다.
방금 이것을 우연히 발견 하고이 스크립트를 사용했지만 .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
공백 find
및 IFS
마술 (파일 이름에는 실제로 줄 바꿈이 포함될 수 있으므로 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는 주요 병목 현상이 될 것입니다.
* 만이 예되면 잠재적 인 경쟁 상태가 마이너 (!) 참고은 (물론 다른 솔루션 적용) .svn
및 foo
디렉토리의 파일과 .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
.
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
.svn
디렉토리가 비어?