単一ファイルでディレクトリを平坦化する

単一ファイルでディレクトリを平坦化する

私は次のディレクトリ構造を持っています:

root_directory
--sub_a
----index.html
--sub_b
----index.html
--sub_c
----index.css
----index.html

これで、ファイルを親ディレクトリに移動し、親フォルダの名前にちなんで名前を変更したいのですが、そのファイルが子ディレクトリにある唯一のファイルである場合にのみ可能です。これにより、次のようにディレクトリが効果的に平坦化されます。

root_directory
--sub_a.html
--sub_b.html
--sub_c
----index.css
----index.html

これを達成するための賢明な方法はありますか?できますが、find . -name 'index.html'ディレクトリにそのファイル以外のファイルが含まれているかどうかをさらに確認する方法がわかりません。これらのファイルのリストがあれば上に移動できますが、(mv path/index.html ..)何らかの方法でフォルダ名を再利用して名前を変更する方が賢明かもしれません。

ベストアンサー1

sub_x通常のファイルのみが含まれているが、1つ以上のサブディレクトリや他の種類のファイルまたはシンボリックリンクを含むディレクトリなど、ディレクトリの下にサブディレクトリがないと仮定すると、ファイル名を親ディレクトリにsub_x変更するように求められます。削除されましたのでご注意ください。

# !/bin/bash 

find /path/to/root_directory/ -type d -execdir bash -c '
    for file in "$1"/*; do
        [[ -f "$file" ]] && (( $((++filesCount)) > 1 )) && exit 1;
    done;
    ((filesCount==1)) && echo mv -v "$file" "${file%/*}.${file##*.}" && echo rm -r "$1"
' _ {} \; 2>/dev/null

テスト実行出力:

mv -v ./sub_b/index.html ./sub_b.html
rm -r ./sub_b
mv -v ./sub_a/index.html ./sub_a.html
rm -r ./sub_a

echo実行するコマンドmvrmコマンドの実際の操作からsを削除します。結果:

root_directory
 ├── sub_a.html
 ├── sub_b.html
 └── sub_c
     ├── index.css
     └── index.html

find ... -type d -execdir bash -c '...' _ {} \;

findディレクトリのみ-dとインラインスクリプトの実行bash -c '...' 以内に(このタスクの使い方-execdir)見つけたすべてのディレクトリについて。


for file in "$1"/*; do
    [[ -f "$file" ]] && (( $((++filesCount)) > 1 )) && exit 1;
done;

返されたディレクトリパス内のすべてのファイルを繰り返し、ファイルであることを$1確認してから-f、変数を増やし、その値が1を超えていることを確認し(ディレクトリに少なくとも2つのファイルがあることを意味します)、そうであればインラインスクリプトを終了します。コマンドの処理を続行するには、find次のディレクトリを読みます。exit処理時間を短縮するために使用され、そのディレクトリ内のファイルは、そのディレクトリ(ファイルが1つしか含まれていないディレクトリ)の基準を満たしていないため、まだ計算されません。


((filesCount==1)) && mv -v "$file" "${file%/*}.${file##*.}" && rm -r "$1"

filesCountが1であることを確認してからファイル名を変更してディレクトリを削除すると、使用方法がわかります${file%/*}${file##*.}シェルパラメータ拡張

おすすめ記事