.svnフォルダーが含まれている場合でも、すべての空のフォルダーを削除します


6

ディレクトリ内のすべての空のフォルダーを削除しようとしています。ただし、find . -type f -emptyすべてのフォルダーには隠し.svnフォルダーが含まれているため、何も見つかりません。

これを回避するにはどうすればよいですか?


ある.svnディレクトリが空の?
デニスウィリアムソン

いいえそうではありません。Ollisソリューションが機能すると思います。ただし、まだテストしていません。
アタマンロマン

回答:


1

可能であれば、最初にすべての.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が削除されます(他のファイルやフォルダーがない場合は、たとえば削除されます)。


3

小さな変更(ディレクトリを単に印刷し、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からディレクトリを削除します。
gioele

2

私はこれにつまずいたので、このスクリプトを使用しましたが、.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

0

空白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グロブは、任意の問題のディレクトリ名の文字に対して安全でなければなりません。グロブがします常にの場合ではありませんこれは、バッシュで安全に拡張しlsfind最後のスラッシュは、我々は唯一の一致を確認します、などのフォルダの名前.svnではなく、通常のファイル(ただし、実際のコーナーケースを、)。
  • 一致する.svnディレクトリを持つフォルダーに含まれるファイルの名前は、配列にまとめられます。この配列内のアイテムの数が1(つまり、.svn構造上*が知っているフォルダ)が存在する場合、それが探しているものです。

Bashビルトインのみを使用するためfind、に余分なシステムフォークを発行するよりも高速である必要がありますが、違いはほとんど目立たず、I / Oが主なボトルネックになります。


*:マイナー追記(だけでなく他のソリューションに適用されます):そこ例のみがあれば潜在的な競合状態がある.svnfoo、ディレクトリ内のファイル、および.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ます。


0
  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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.