bash でファイルとディレクトリの名前を再帰的に変更する最適な方法は何ですか?

bash でファイルとディレクトリの名前を再帰的に変更する最適な方法は何ですか?

多数のファイルとディレクトリの名前を一括で変更するスクリプトを作成しようとしています。 しかし、すべてのファイルとサブファイルを移動させるのに問題があります。

私の今のスクリプトはこれです

#! /bin/bash

function _setname {
    for file in "$@"
    do
        oldname=$(basename "${file}")
        newname=$(echo "${oldname}" | tr '?%*:|' '_' )
        echo "${newname}"
        [ ! "${oldname}" = "${newname}" ] && mv "${oldname}" "${newname}"
    done
}
function _recursivename {
    for file in "$@"
    do
        currentpath="$(pwd)"
        cd "$(dirname ${file})"
        oldname="$(basename ${file})"
        newname="$(_setname ${oldname})"

        [ -d "${newname}" ] && _recursivename ./"${newname}"/*

        cd "${currentpath}"
    done
}
_recursivename "${@}"
exit

ディレクトリ ツリーの一番下に到達して上に戻る必要がある場合、currentpath上書きされていて、2 番目のサブディレクトリを探すために先頭に戻らないため、処理が中断されます。

currentpathなぜ上書きされるのか、またそれを適切に行うにはどうすればよいのかわかりません。

編集: 宣言する必要がありましたlocal。関数内で定義することでローカルに宣言されると思いました。

答え1

関数内で使用される変数はグローバルです。つまり、関数内で変数に値が割り当てられている場合、その値は呼び出し元からアクセスできます。関数内でのみ使用され、呼び出し元からはアクセスできない変数を宣言する場合は、この変数を宣言する必要がありますlocal。たとえば、関数の先頭に次の行を追加できます_recursivename

local currentpath

これは、ローカル変数のプライベート コピーを保持し、呼び出しごとに一意の値を保持する必要のある再帰関数の場合に特に重要です。

関連情報