扁平化資料夾結構

扁平化資料夾結構

我有這個資料夾結構:

├── foo1
│   ├── bar1.txt
│   └── bar2.txt
├── foo2
│   ├── bar3.txt
│   └── bar4 with a space.txt
└── foo3
    └── qux1
        ├── bar5.txt
        └── bar6.txt

我想將其扁平化,在每個資料夾層級之間使用下劃線:

├── foo1_bar1.txt
├── foo1_bar2.txt
├── foo2_bar3.txt
├── foo2_bar4 with a space.txt
├── foo3_qux1.bar6.txt
└── foo3_qux1_bar5.txt

我環顧四周,沒有找到任何有效的解決方案,主要是因為我的問題有兩個特殊性:根資料夾內可能有多個資料夾級別,而且有些文件可能有空格。

知道如何在 bash 中實現這一點嗎?謝謝!

編輯:運行格倫傑克曼提出的答案我得到這個:

在此輸入影像描述

一級資料夾有兩個底線。知道如何避免這種情況或只是重命名它,以便這只是一個下劃線嗎?謝謝。

答案1

find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;

echo如果您對它的工作感到滿意,請將其刪除。不要擔心 echo 命令不顯示引號,腳本將正確處理帶有空格的檔案。

如果您想要刪除現在空的子目錄:

find */ -depth -type d -exec echo rmdir '{}' \; 

答案2

使用perl的重命名:

find . -depth -type f -exec rename 's@(?<!\.)/@_@g' -- {} \;

輸出

$ find -type f
./foo2_bar4 whit a space.txt
./foo3_qux1_bar6.txt
./foo2_bar3.txt
./foo3_qux1_bar5.txt
./foo1_bar2.txt
./foo1_bar1.txt

筆記

  • 我用一個消極地向後看 (?<!\.)不要碰第一個./
  • 我保留空目錄,請隨意:

    find . -depth -type d -exec rm {} \;

警告還有其他同名的工具可能能夠也可能無法做到這一點,所以要小心。

如果執行以下命令 ( GNU)

$ file "$(readlink -f "$(type -p rename)")"

你有一個像這樣的結果

.../rename: Perl script, ASCII text executable

且不包含:

ELF

那麼這似乎是正確的工具 =)

如果不是,則將其設為預設值(通常已經是這種情況)Debian並衍生如下Ubuntu

$ sudo update-alternatives --set rename /path/to/rename

(替換為您的命令/path/to/rename的路徑。perl's rename


如果您沒有此命令,請搜尋套件管理器來安裝它或手動做


最後但並非最不重要的一點是,這個工具最初是由 Perl 之父 Larry Wall 編寫的。

答案3

pax

pax -Xrwls '|/|_|g' */ "$PWD"

這將在當前目錄中創建一個指向其子目錄中所有文件的硬鏈接,_並將/.然後您可以檢查結果並使用以下命令刪除所有子目錄...

rm -rf */

……一旦您確認結果符合您的喜好。

答案4

您可以嘗試使用以下命令。

$ find -type f -exec bash -c 'mv $0 $(echo $0|sed "s/\//_/2")' {} \;

上述命令將移動文件,並且目錄將保留,稍後可以刪除。

$ ls
foo1_bar1.txt  foo1_bar2.txt  foo2_bar3.txt  foo2_bar4.txt  foo3_bar5.txt  foo3_bar6.txt

相關內容