Bash

重命名目錄 bash 腳本 - 目標…沒有這樣的文件或目錄

  • January 6, 2019

我一直在一個簡單的目錄結構上對此進行測試。

我正在嘗試將名稱為“Season”的任何目錄和/或子目錄更改為“Sn”。我到了腳本會改變我想要的東西的地步……除了頂級目錄,如下面的列表所示 - “第 1 季”“第 2 季”“第 3 季”。

目錄結構:

.
├── AnotherShow
│   ├── Sn1
│   ├── Sn2
│   ├── Sn3
│   └── Sn4
├── Movie1
│   ├── Sn1
│   └── Sn2
├── Movie2
│   ├── Sn1
│   ├── Sn2
│   ├── Sn3
│   └── Sn4
├── Movie3
│   ├── Sn1
│   └── Sn3
├── Movie4
│   ├── Sn2
│   └── Sn3
├── Season 1
├── Season 2
├── Season 3
├── Show
│   ├── Sn1
│   ├── Sn2
│   ├── Sn3
│   ├── Sn4
│   └── Sn5
└── TV
   ├── Sn1
   ├── Sn2
   ├── Sn3
   └── Sn4

我的腳本是:

array="$(find . -maxdepth 2 -type d -iname 'Season*' -print)"; # A more refined way to search for Seasons in    a directory.
for dir in "${array[@]}"; do # Put this list into an array.  Surround the array with quotes to keep all space   s (if any) together.
  new="$(echo "$dir" | sed -e 's/Season 0/Sn/' -e 's/Season /Sn/')"; # Only change Season 0 to SN.  Leave othe   rs alone.
  sudo mv -v "$dir" "$new" && echo Changed "$dir" to "$new"; 
done                                                           

問題是您不是在創建數組,而是在創建字元串。您可以通過嘗試列印數組的第一個元素來輕鬆測試:

$ array="$(find . -maxdepth 2 -type d -iname 'Season*' -print)"; 
$ echo $array
./Season 3 ./Season 1 ./Season 2

看起來不錯吧?但如果那是一個數組,您將能夠分別列印每個元素。不幸的是,上面是一個簡單的字元串1而不是一個數組:

$ echo ${array[0]}
./Season 3 ./Season 1 ./Season 2
$ echo ${array[1]}

該數組實際上由一個字元串組成,這就是“數組” ( ${array[1]}) 的第二個元素為空的原因。在任何情況下,您都不需要數組,只需通讀find(您也不需要-print,預設情況下就是這樣做的)的輸出。您的腳本的工作版本可能是:

#!/usr/bin/env bash
find . -maxdepth 2 -type d -iname 'Season*' | sort -r |
while IFS= read -r dir
do 
   mv "$dir" ${dir/Season /Sn} && echo Changed "$dir" to "$dir/Season /Sn}"; 
done

那裡使用了一些技巧。首先,while循環遍歷結果findfor這與您使用的循環的基本原理相同,但read可以從標準輸入中讀取。

IFS=需要避免在空格上拆分(沒有它,目錄將Season 1被拆分為Seasonand 1)。

-rof read 告訴它不允許反斜杠轉義字元(像\t和被字面處理的東西\n),這確保它可以處理即使是最奇怪的名字。

是必需的sort -r,以便如果您有一個與另一個匹配目錄中的模式匹配的目錄,則子目錄列在父目錄之前。例如:

./Season 12/Season 13
./Season 12

這可確保您在執行mv "Season 12" "Sn12" 執行mv "Season 12"/"Season 13" "Season 12"/"Sn13"。如果你不這樣做,第二個命令將失敗,因為Season 12不再存在。

最後,我刪除了sudo. 您應該改為將腳本作為sudo script.sh. sudo在腳本中進行隨機呼叫絕不是一個好主意。


1我不確定細節,但顯然,bash 將字元串變數視為一個元素的數組。

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