特定のフォルダに拡張子のないファイルのリストがあります。名前を変更して拡張子を追加したいです。名前はUUIDでなければなりません。私はそれらを見つける方法を知っており、UUIDを生成するためのユーティリティ「uuidgen」があります。残りはどうしますか?
find . -type f -name 'file*' # ??? -exec .... ???
答え1
努力する:
find . -type f -name 'file*' -execdir sh -c 'mv "$1" "$(uuidgen).ext"' Renamer {} \;
どのように動作しますか?
find . -type f -name 'file*' -execdir ... \;
この部分はあなたに慣れているようです。 glob と一致する名前のファイルを探し、
file*
そのファイルに対してコマンドを実行します。...
この場合は、...
次のように置き換えます。sh -c 'mv "$1" "$(uuidgen).ext"' Renamer {}
これはシェルを起動し、mvコマンドを実行し、ファイル名を
$1
.(シェルに割り当てられ、エラーメッセージが生成されたときにシェルで使用されるRenamer
任意の文字列)として使用できるようにします。 、これはシェルがに割り当てるものです。シェルコマンドを見てみましょう。$0
find
{}
$1
mv "$1" "$(uuidgen).ext"
次に、ファイル名をから
$1
変更しますuuidgen
。$1
ファイル名にはスペースやその他の難しい文字を含めることができるため、単語の区切りやシェル拡張から名前を保護するために二重引用符で囲みました。
2つの理由で-execdir
代わりに使用します。-exec
コマンドが簡単になります
mv
。名前が変更されたファイルが同じディレクトリに残っていることを確認するために、追加のコードは必要ありません。-execdir
より安全:ディレクトリ名が変更された場合しかし、コマンドfind
は実行中ですが-exec
実行されておらず、-execdir
ひどく失敗する可能性があります。
なぜ新しいシェルを起動するのですか?
以下を試してみたいかもしれません。
find . -type f -name 'file*' -execdir mv {} "$(uuidgen).ext" \; # Don't do this
ここでの問題uuidgen
は一度だけ実行できることです。シェルが実行されますuuidgen
今後でもコマンドfind
を起動します。したがって、すべてのmv
コマンドに同じ宛先ファイル名。私たちはuuidgen
一度走りたいすべてファイルが見つかりましたfind
。そのため、コマンドを実行して実行する必要がありますmv
。uuidgen
sh
より効率的なバージョン
上記のコードは、見つかったファイルごとに新しいシェルを起動します。これとは対照的に、次のアプローチでは、起動されたシェルプロセスごとに何千ものファイルを処理できます。
find . -type f -name 'fi*' -execdir sh -c 'for f; do mv "$f" "$(uuidgen).ext"; done' Renamer {} +