指定された名前のディレクトリを探し、その内容を1つ上のレベルに移動するには?

指定された名前のディレクトリを探し、その内容を1つ上のレベルに移動するには?

私は与えられた名前を持つすべてのディレクトリを見つける方法を知っています。

find . -name unnecessary_dir_level

ファイルを親ディレクトリに移動する方法は次のとおりです。

mv * ..

どのように結合しますか? - はい

find . -name unnecessary_dir_level -exec mv {}/* {}/.. \;

混乱を招くことなくこの作業を完了したいですか?それともどうなりますか?私はアドバイスなしでこれを試したくありません(そしてディレクトリが大きすぎて合理的な時間にバックアップすることはできません)。

ベストアンサー1

(継続的に中断されない)オプションをサポートする実装では、zsh次のことができます。mv-n

for dir (**/unnecessary_dir_level(ND/od)) () {
  (( ! $# )) || mv -n -- $@ $dir:h/ && rmdir -- $dir
} $dir/*(ND)

どこ:

  • for var (values) cmdループの短いバージョンです(プログラミング言語でより一般的です)for
  • **/: グローバル演算子、つまりあらゆるレベルのサブディレクトリ
  • Nglob修飾子:nullglobこのglobを有効にします(一致する項目がなくても文句を言わないでください)。
  • Dglob修飾子:dotglobこのglobを有効にします(隠しファイルを含む)。
  • /glob修飾子:ファイル形式に制限目次
  • odglob 修飾子: order by depth (該当する四半期より前)
  • () { body; } args:パラメータを持つ匿名関数。
  • ここパラメータ存在$dir/*(ND): 隠しファイルを含むすべてのファイル$dir
  • これこれらのファイル(存在する場合)に対して実行し、空でなければならないmvファイルrmdirに対して実行します。$dir
  • $dir:h、(cshなどのディレクトリ名)h$dir

次のmv * ..2つのアカウントは間違っています。

  • オプション区切り文字がありません。mv -- * ..
  • 隠しファイルがありません:mv -- *(D) ..zsh、((shopt -s nullglob failglob; exec mv -- * ..)in bash
  • さらに:親ファイルに同じ名前のファイルがあると、データが失われる可能性があります。
find . -name unnecessary_dir_level -exec mv {}/* {}/.. \;

{}/*globが呼び出される前にシェルによって拡張されるため、機能しませんmv。現在のディレクトリに呼び出し元ディレクトリがある場合は、別のディレクトリに展開され、{}誤ったファイルが移動されます。


find次のようにbash同様の操作を実行できます。

find . -depth -name unnecessary_dir_level -type d -exec \
  bash -O nullglob -O dotglob -c '
    for dir do
      set -- "$dir"/*
      (( ! $# )) || mv -n -- "$@" "${dir%/*}" && rmdir -- "$dir"
    done' bash {} +

おすすめ記事