ディレクトリの名前を変更するbashスクリプト - 宛先...そのファイルまたはディレクトリはありません。

ディレクトリの名前を変更するbashスクリプト - 宛先...そのファイルまたはディレクトリはありません。

私はこれを単純なディレクトリ構造でテストしてきました。
「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                                                           

ベストアンサー1

問題は配列を作成するのではなく、文字列を作成することです。配列の最初の要素を印刷すると、簡単にテストできます。

$ 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]}「配列」の2番目の要素()は空です。いずれにせよ、このために配列を使用する必要はなく、読み込みの出力を使用するだけです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結果を繰り返しますfind。これは使用したループと同じ基本原理ですが、標準入力からの読み出しとfor組み合わせられます。read

空白による分割を避ける必要がありますIFS=(空白がない場合、ディレクトリはSeason 1およびで分割されます)。Season1

of readはバックスラッシュエスケープ文字(および文字通り処理される文字)を -r許可しないように指示し、最も奇妙な名前を処理できるようにします。\t\n

これはsort -r、一致する他のディレクトリのパターンと一致するディレクトリがある場合に、サブディレクトリが親ディレクトリの前にリストされるようにするために必要です。たとえば、

./Season 12/Season 13
./Season 12

これにより実行が保証されます。mv "Season 12" "Sn12" 後ろにランニングmv "Season 12"/"Season 13" "Season 12"/"Sn13"。そうしないと、2番目のコマンドはSeason 12もう存在しないため失敗します。

最後にを削除しましたsudo。スクリプトをとして実行する必要がありますsudo script.shsudoスクリプトからランダムに呼び出すことは決して良い考えではありません。


1詳細はわかりませんが、bashは文字列変数を1つの要素の配列として扱います。

おすすめ記事