シンボリックリンクで指定されない限り、ディレクトリの削除

シンボリックリンクで指定されない限り、ディレクトリの削除

次のディレクトリ構造があります。名前付きファイルがあるディレクトリを見つけて、特定log.xmlのシンボリックリンクが指すディレクトリを除くすべてのディレクトリを完全に削除する必要があります。

たとえば、/dir1/main/app1/v004/および/dir1/main/app2/v004/log.xmlシンボリックリンクとして指定されるため、削除しないでください。

また、シンボリックリンクが指すディレクトリ以外のディレクトリを見つけずにどのように削除しますかlog.xml

正しいソリューションを提供するのに役立ちますか?

/dir1/main/app1/v001/
/dir1/main/app1/v002/log.xml
/dir1/main/app1/v003/log.xml
/dir1/main/app1/v004/log.xml
/dir1/main/app1/v005/log.xml
/dir1/ln1/app -> /dir1/main/app2/v004

/dir1/main/app2/v001/
/dir1/main/app2/v002/log.xml
/dir1/main/app2/v003/log.xml
/dir1/main/app2/v004/log.xml
/dir1/main/app2/v005/log.xml
/dir1/ln2/app -> /dir1/main/app2/v004

答え1

appv001(除外log.xml)とv004(シンボリックリンクで指す)を除いて、ディレクトリ内のすべてのサブディレクトリを削除するとします。

for topdir in /dir1 /dir2; do

    for dirpath in "$topdir"/main/app/*/; do
            if [ -e "$dirpath/log.xml" ] && ! [ "$dirpath" -ef "$topdir"/ln/app ]
            then
                    printf 'Would remove "%s"\n' "$dirpath"
                    # rm -rf "$dirpath"
            fi
    done

done

外部ループは、2つの最上位ディレクトリを繰り返すために使用されます/dir1(これをグローブパターンとして使用/dir2できます)。/dir[12]最上位ディレクトリの名前がtopdir変数に保存されます。

内部ループは以下のサブディレクトリを介して繰り返さappれます$topdir。サブディレクトリに名前付きエントリlog.xml(最初のテスト、with)が含まれており、シンボリックリンクがそのディレクトリ(2番目のテスト、with)を指し-eていない場合は、そのディレクトリを削除できます。"$topdir"/ln/app-ef

この-eテストは、指定されたパス名が存在するかどうかの標準テストです。この-efテストは非標準ですが、シェルbashによって実装され、シンボリックリンクを確認した後、両方のパス名が同じファイル(またはこの場合はディレクトリ)を参照するかどうかをテストします。

実際の削除内容は安全のためコメントアウトされています。このコマンドをアクティブにする前に、以前にバックアップしたデータをテストする必要がありますrm

という内容が含まれているかどうかにかかわらず、サブディレクトリを削除するには、ステートメントが次のように見えるようにテストを削除しますlog.xml-eif

if ! [ "$dirpath" -ef "$topdir"/ln/app ]; then
        printf 'Would remove "%s"\n' "$dirpath"
        # rm -rf "$dirpath"
fi

答え2

GNUfindにはオプションがあります-samefile。これを機能させるには、-Lオプションを含める必要があります。

次の2つのコマンドの出力を見てください。

(cd /dir1 ; find -L . -samefile ln/app ) # your file and link

(cd /dir1 ; find -L . -not -samefile ln/app ) # everything other than your file and link

2番目は削除したいファイルのリストを生成する必要があります。ディレクトリ以外のファイルだけを一覧表示したい場合があります。その場合は、以下を追加してください。-type f

find -L . -type f -samefile ln/app)

ファイルを削除することは、findコマンドにexecアクションを追加するのと同じくらい簡単です。例えば-exec rm -v {} \;

関連情報