親ディレクトリと子ディレクトリの名前が同じ場合は、ファイルを親ディレクトリに移動します。

親ディレクトリと子ディレクトリの名前が同じ場合は、ファイルを親ディレクトリに移動します。

同じ名前のサブディレクトリをディレクトリから取得し、サブディレクトリ内のすべてのファイルを親ディレクトリに移動する方法が必要です。したがって、次の方法を使用して空のディレクトリをすべて削除/recup-dir1/recup-dir1/files to /recup-dir1/files. できるため、サブディレクトリを空白にすることができます。 find . -type -d -empty -delete

だから問題は、どのディレクトリに同じ名前のサブディレクトリがあり、どのディレクトリにないのかわからないということです。

擬似コードにはこのようなものが必要です。

While more directories are unchecked
get name-x of  next dir
   enter dir  
   If name-x/name-x exist
   move all files in name-x/name-x to name-x
   mark dir as done
next 

私の推測では、小さなPythonスクリプトを作成して、同じ名前のサブディレクトリを含むすべてのディレクトリのリストを作成し、次のコマンドを使用してこのリストを繰り返すことです。 find something something -exec mv

たぶんこれはbashスクリプトを介して行うことができ、他の解決策が存在するかもしれません。いくつかのrsyncコマンドと似ていますが、rsyncを使用してこの混乱を作成した可能性があるため、これは解決策ではないと思います。

編集:これはツリー出力の実際の部分です。最上位ディレクトリは/mnt/external-disk/tst-backup内にあり、下位レベルには下位ディレクトリはありません。

│   └── recup_dir.1
├── recup_dir.10
│   └── recup_dir.10
├── recup_dir.100
│   └── recup_dir.100
├── recup_dir.102
│   └── recup_dir.102
└── recup_dir.1020
    └── recup_dir.1020

ベストアンサー1

これにより、zsh次のことができます。

for dir in **/*(NDodoN/e['[[ $REPLY:t = $REPLY:h:t ]]']); do
  contents=($dir/*(NDoN))
  (( $#contents == 0 )) ||
    mv -- $contents $dir:h/ &&
    rmdir -- $dir
done

どこ:

  • **/*(qualifiers)glob修飾子を使用した再帰的globbing
  • N:nullglob:一致するものがなくても文句を言わないでください。
  • D:dotglob:隠しファイルを含みます。
  • od:順次深さ優先(葉が自分のいる枝より先に来る)
  • oN: それ以外の場合は、ファイルのリストを並べ替えることを気にしないでください。
  • /:ディレクトリタイプファイルに制限されます。
  • e['expression']expressionコードがtrueを返すファイルを制限します(現在のファイルパスが保存されている場所$REPLY)。
  • $REPLY:t:ファイルの尾(デフォルト名)
  • $REPLY:h:t:ファイルヘッダーの終わり(ディレクトリ名))

bash4.4+ および GNUfindまたはほとんどの BSD では、find次のようにできます。

shopt -s nullglob dotglob
readarray -td '' dirs < <(
  LC_ALL=C find . -depth -regex '.*\(/[^/]*\)\1' -type d -print0
)
for d in "${dirs[@]}"; do
  contents=("$d"/*)
  (( ${#contents[@]} == 0 )) ||
    mv -- "${contents[@]}" "${d%/*}/" &&
    rmdir -- "$d"
done

./path/to/dir/dir今回は、デフォルトの正規表現を使用して逆参照ファイルを一致させるために正規表現が使用されます。

おすすめ記事