2つの異なるディレクトリ間で共通のサブディレクトリ名を識別して削除する

2つの異なるディレクトリ間で共通のサブディレクトリ名を識別して削除する

に数百のサブディレクトリを持つ2 つのディレクトリdir1とがあります。 と に共通するサブディレクトリ名の情報だけが必要で、からそれらを体系的に削除します。 ファイルやファイルの内容を比較する必要はありません。dir2depth 1dir1dir2dir2

diff -qr dir_one dir_two | sort

ファイル名も生成されますが、現時点では興味がありません。

答え1

あなたのユースケースでは、識別する共通ディレクトリはrm -rf存在しないディレクトリを無視するだけです。

だから、find 全てのディレクトリdir1を削除 dir2:

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 rm -rf --

いくつかの説明。デフォルトでは、findは完全なパスですべてのディレクトリを印刷しますdir1。したがって、-printf先頭のディレクトリ (%f) のないファイル名と、削除する他のパス "dir2" のみを印刷するために を使用しています。さらに、スペースを含むファイル名に関してこれをすべて安全にするxargオプションを使用するには、文字列を改行ではなくヌル バイト '\0' で終了します。次に、は標準入力を読み取り、すべての文字列を引数として追加してコマンドを実行します。-0xargsrm

実際に削除する前に、コマンドechoのみを印刷するようにコマンド ラインを追加してテストすることができますrm

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 echo rm -rf --

のみリストls代わりに使用できる共通ディレクトリrm(存在しないディレクトリを無視するには 2>/dev/null を追加します):

find dir1 -mindepth 1 -maxdepth 1 -type d -printf "dir2/%f\0" |xargs -0 -r ls -d -- 2>/dev/null

答え2

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) <( cd dir2 && find -maxdepth 1 -type d | sort ) | ( cd dir2 && xargs rm -rf )

読みやすくするために改行を入れます。

comm -1 -3 <( cd dir1 && find -maxdepth 1 -type d | sort ) \
           <( cd dir2 && find -maxdepth 1 -type d | sort ) \
                | ( cd dir2 && xargs rm -rf )

説明

find -maxdepth 1 -type d

サブディレクトリのないディレクトリのみをリストします。

cd dir1 && find -maxdepth 1 -type d | sort

まずディレクトリを変更し、次にディレクトリを一覧表示します。

<( ... )

プロセス置換

comm -1 -3 <( ... ) <( ... )

最初の入力と 2 番目の入力を受け取り、 2 番目の入力に固有の行を出力します。 実際には、 にあるdir2が にはないディレクトリが出力されますdir1

... | ( cd dir2 && xargs rm -rf )

作業ディレクトリを に変更し、前のコマンドの出力を引数としてdir2を実行します。 実際には、にあるが にはないrm -rfディレクトリが削除されます。dir2dir1

まずパイプを削除してxargs出力を検査してテストします。

答え3

find dir1 dir2 -maxdepth 2 | egrep '/' | xargs --max-args 1 basename | sort | uniq -c  | egrep -v '^      1 ' | while read n de ; do echo rm -rfv dir2/$de ; done

正しい場合はエコーを削除します。

関連情報