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

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

次のディレクトリ構造があります。名前付きファイルがあるディレクトリを見つけて、特定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

おすすめ記事