ディレクトリを階層に再構成する

ディレクトリを階層に再構成する

数千のフォルダがある次の種類のフォルダ構造があります。

フォルダ名自体が異なる名前などを持っています。

.test
.test.subfolder
.test.subfolder.subsubfolder

.folder
.folder.one
.folder.two
.folder.one.one

.test私が達成しなければならないことは次のとおりです。たとえば、フォルダの名前をfromに変更し、testフォルダ.test.subfolderがフォルダなしでフォルダ内にあるように.subfolder移動し、そのフォルダの内側と内側になるようにします。test..test.subfolder.subsubfoldersubfoldertestsubsubfoldertest/subfolder

フォルダが多いので再帰が必要です。フォルダ内のファイルはそのまま残す必要があることを覚えておいてください。

これは可能ですか?

答え1

このbashスクリプトは必要なタスクを実行します。

#!/bin/bash
for dir in .*/ ; do
    [[ $dir == ./ || $dir == ../ ]] && continue  # Skip the special dirs
    new=${dir#.}                                 # Remove the dot at the beginning
    new=./${new//.//}                            # Replace dots with slashes, prepend ./
    new=${new%/}                                 # Remove the trainling slash
    mkdir -p ${new%/*}                           # Create the parent dir
    mv "$dir" "$new"                             # Move the dir to destination
done

答え2

はい、可能です。あなたがすべきことは、パス内のすべてのファイル名を読み、スペース、ドットなどを考慮する必要があることです。これを効率的に行うには、次のスレッドを使用できます。サブフォルダ内の特定の拡張子を持つすべてのファイルに対してエレガントな方法でタスクを実行するには?

パス名のファイルを読み込んだら、ルールを作成する必要があります。

たとえば、次の構造を考えてみましょう。

 .test
  .test.subfolder
   .test.subfolder.subsubfolder

あなたが望むのは、各ファイル名でsubという単語の発生回数を数えることです。したがって、数が0の場合は親フォルダ、数が1の場合は最初のレベルのサブフォルダ、数が3の場合は2番目のレベルのサブフォルダです。あなたが提供した構造から派生します)

したがって、可能な疑似コードは次のとおりです。

  if(filename contains(".test"))
  {
   searchCount("sub");
   if(count ==0)
   parent();
   else if(count ==1)
   1stLevelChild();//and so on
  }

これで、取得した結果に応じて、移動コマンドを使用してファイルを適切なフォルダに移動できます。

答え3

zshではとても簡単です。ありがとうございます。zmv。ワイルドカードは.*ファイル名をアルファベット順に拡張するため、親になるディレクトリの名前は常にサブディレクトリの前に変更されます。つまり、test名前を変更するとすでに存在します。.test.subfolder

zmv '.(*)' "${1//./\/}"

関連情報