数千のフォルダがある次の種類のフォルダ構造があります。
フォルダ名自体が異なる名前などを持っています。
.test
.test.subfolder
.test.subfolder.subsubfolder
.folder
.folder.one
.folder.two
.folder.one.one
.test
私が達成しなければならないことは次のとおりです。たとえば、フォルダの名前をfromに変更し、test
フォルダ.test.subfolder
がフォルダなしでフォルダ内にあるように.subfolder
移動し、そのフォルダの内側と内側になるようにします。test
.
.test.subfolder.subsubfolder
subfolder
test
subsubfolder
test/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//./\/}"