Linux

用單個文件展平目錄

  • December 9, 2020

我有以下目錄結構

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 ..),但是以某種方式重用文件夾名稱來重命名它們可能更聰明。

假設目錄下沒有子目錄sub_x,就像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的 s 以執行mvrm命令的實際操作。結果:

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用於縮短處理時間,並且不繼續計算該目錄中的文件,因為它不符合我們對該目錄的條件(僅包含一個文件的目錄)。


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

檢查 filesCount 是否等於 1,然後重命名文件並刪除目錄;${file%/*}並且${file##*.}使用的是已知的 Shell Parameter-Expansion

引用自:https://unix.stackexchange.com/questions/623659