Bash

父子目錄同名,移動文件到父目錄

  • June 7, 2021

我需要一種方法來搜尋具有相同名稱的子目錄的目錄,然後將子目錄中的所有文件移動到父目錄。因此, /recup-dir1/recup-dir1/files to /recup-dir1/files. 子目錄可以留空,因為我可以使用類似 find . -type -d -empty -delete 刪除所有空目錄的方法

所以問題是我不知道哪些目錄中有同名的子目錄,哪些沒有。

在虛擬碼中,我需要這樣的東西。

While more directories are unchecked
get name-x of  next dir
  enter dir  
  If name-x/name-x exist
  move all files in name-x/name-x to name-x
  mark dir as done
next 

我最好的猜測是創建一個小python腳本來列出所有具有相同名稱的子目錄的目錄,並通過類似的命令循環該列表 find something something -exec mv

也許這可以通過 bash 腳本來完成,或者存在其他解決方案。就像一些 rsync 命令一樣,但是由於我可能使用 rsync 創建了這個混亂,我認為這不會是解決方案。

編輯:這是樹輸出的實際部分:頂層目錄位於 /mnt/external-disk/tst-backup 內部 較低級別沒有子目錄。

│   └── recup_dir.1
├── recup_dir.10
│   └── recup_dir.10
├── recup_dir.100
│   └── recup_dir.100
├── recup_dir.102
│   └── recup_dir.102
└── recup_dir.1020
   └── recup_dir.1020

使用zsh,您可以執行以下操作:

for dir in **/*(NDodoN/e['[[ $REPLY:t = $REPLY:h:t ]]']); do
 contents=($dir/*(NDoN))
 (( $#contents == 0 )) ||
   mv -- $contents $dir:h/ &&
   rmdir -- $dir
done

在哪裡:

  • **/*(*qualifiers*)使用 glob 限定符的遞歸 globbing
  • N: nullglob: 如果沒有匹配就不要抱怨
  • D: dotglob: 包含隱藏文件
  • od:首先訂購深度(在它們所在的分支之前離開)。
  • oN:否則不要為文件列表排序而煩惱。
  • /: 限制為目錄類型的文件。
  • e['*expression*']: 僅限於expression程式碼返回 true 的文件(目前文件路徑儲存在其中$REPLY)。
  • $REPLY:t:文件的尾部(基本名稱)
  • $REPLY:h:t:文件頭的尾部(目錄名))

使用bash4.4+ 和 GNUfindfind大多數 BSD,您可以執行以下類似操作:

shopt -s nullglob dotglob
readarray -td '' dirs < <(
 LC_ALL=C find . -depth -regex '.*\(/[^/]*\)\1' -type d -print0
)
for d in "${dirs[@]}"; do
 contents=("$d"/*)
 (( ${#contents[@]} == 0 )) ||
   mv -- "${contents[@]}" "${d%/*}/" &&
   rmdir -- "$d"
done

這次使用正則表達式來匹配./path/to/dir/dir使用基本正則表達式反向引用的文件。

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