このスクリプトがどのように機能するかを説明できる人はいますか?

このスクリプトがどのように機能するかを説明できる人はいますか?

私はファイル名とディレクトリ名を小文字に変更し、すべてのスペースを「-」に置き換えるスクリプトを探しています。私は別のスクリプトで以下のスクリプトを見つけましたが、それがどのように機能するかを完全に理解していません。誰でも私を案内していただきありがとうございます。

find ./* -depth -type d -exec sh -c '
t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
[ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

答え1

find ./* -depth -type d -exec sh -c ' ... ' {} \;

findツリー内のすべてのディレクトリ(-type d)を削除し、各ディレクトリに対してシェルフラグメントを実行して$0現在の名前に設定します。-depth各ディレクトリの内容を最初に処理し、ディレクトリ自体が最後に処理するようにします。 (そうでない場合は、名前を変更すると問題が発生する可能性があります。)

t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");

${0%/*}最後のスラッシュとその後のすべての項目を削除します$0。つまり、ディレクトリ名を保持します。${0##*/}基本的にその逆です。 (それらの種類はパラメータ拡張)は、printf | tr名前の最後の部分を小文字に変更するために使用されます。結果は(に割り当てられますt$(...)コマンドの置き換え)

[ "$t" = "$0" ] || mv -i "$0" "$t"

テストinの新しい名前tとinの古い名前が$0同じであることを確認してください。いいえその後、電話mvをかけます。


ここで愚かな部分は、同じようfindに呼び出すことができ、ファイル名を見つける操作なので、find . -depth ...ファイル名ワイルドカード()は必要ありません。代わりに、ファイル名のディレクトリ部分を処理する必要はありません。ターゲットファイル名の使用は少し誤った形式です。これはスクリプト自体の名前を意味します。find ./*find-execdir-exec$0


ファイルとディレクトリの名前を変更し、スペースをダッシュ​​に変更することについて言及しました。私が知る限り、ここのコマンドはどちらも行いません。find -type dディレクトリのみをキャプチャするには、を使用して-type f通常のファイルのみをキャプチャするか、型を無視するようにしてください。また、空白の内容はありませんが、たとえば、すべての空白をダッシュ​​に変更することtrで変更できます。tr "[:upper:][:space:]" "[:lower:][-*]"

答え2

rename私は多くのディストリビューションで利用可能なlarry wallを使います。 Debianと派生製品が含まれています。

rename -E 's/-//g' -E 's/(.*)/\L$1/g' *

最初の表現S何でも検索して交換してください-。 2番目の式は(.*)内容が同じです$1が、小文字に変換されたすべての項目を検索して置き換えます。\L

答え3

提供されたスクリプトは、ディレクトリを抽出して小文字に変更する作業を実行します。white space変化はありません-

スペースを-に変更し、文字列を小文字に変更するには、sedが正しく機能します。

sed -e 's/[[:space:]]/-/g' -e 's/\(.*\)/\L\1/'

したがって、次のスクリプトが機能する必要があります。

find ./* -depth -type d -execdir sh -c '
t=$(printf %s "${1}" | sed -e 's/[[:space:]]/-/g' -e "s/\(.*\)/\L\1/")
[ "$t" = "$1" ] || echo mv -i "$1" "$t"
' sh {} \;

ディレクトリ名の抽出を防ぐには、-depthとを使用します。選択した要素をディレクトリに限定します。-execdir
type d

関連情報