ファイルセットのすべてのコロンをダッシュ​​に置き換えますか?

ファイルセットのすべてのコロンをダッシュ​​に置き換えますか?

次のコマンドを使用して、特定のサブフォルダのファイル名にあるすべてのコロンをダッシュ​​に置き換えようとしました。

find . -type f -name "*:*" -exec rename -n 's/:/-/g' {} +

しかし、エラーメッセージが表示されます。

rename: not enough arguments

インターネット検索によると、名前が変更されたバージョンが上記のコマンドに必要なバージョンと異なるためです。それでは、このコマンドを名前変更されたバージョンで動作するコマンドに「変換」するにはどうすればよいですか?

私の名前が変更されたバージョンは、「util-linux 2.28.2で名前を変更する」です。

答え1

renameはい、Linuxシステムには関係がなく完全に互換性のない2つの主要なコマンドバリアントがあります。

1(数十年前にサンプルスクリプトから始めて長い間一緒にperl配布されていますが、現在はいくつかの拡張機能を含む1つ以上のスタンドアロンパッケージとして提供されています)。perlこれはシステムで呼び出されるrenameか、時には別のものとして呼び出されます。prenamerename

これがコマンドラインから期待するものです。

renameそして、その有用性は非常に限られていますutil-linux。これはrename.ul一部のシステムで呼び出されることがあります。renameperlrename

この文字列を使用すると、ある文字列を別の文字列にのみ置き換えることができます。これは可能ですが、-execdir rename : - {} +これはコロン(12:30:00.log- > 12-30:00.log)のみを置き換えます。

renameここで手動で実装できます。

find . -name '*:*' -type f -print0 | perl -0ne '
  rename $_, s{[^/]+$}{$& =~ y/:/-/r}res or warn "rename $_: $!"'

(ここではファイルのデフォルト名から:sだけを変更してください。ディレクトリにsが含まれている場合は失敗します。)-:

perlまたは rename を置き換えて呼び出す代わりにシェルを使用しますmv(ここでは、bashおよび ksh パラメータ拡張演算子を使用します。そうでない場合は、使用または置換${var//pattern/replacement}できます)。bashkshzshbash

find . -name '*:*' -type f -exec bash -c '
  for file do
    base=${file##*/}
    mv "$file" "${file%/*}/${base//:/-}"
  done' bash {} +

または、zshそのzmv機能を使用してください。

autoload zmv
zmv '(**/)(*:*)(#qD.)' '$1${2//:/-}'

答え2

いいえrename:

find . -type f -name '*:*' -execdir bash -c 'echo mv "$1" "${1//:/-}"' bash {} \;

表示されているとおりに試してもecho正常に動作すると思われる場合は削除してください。

これは、見つかった各ファイル名を引数として使用して-execdir実行するために使用されます。bash -c 'mv "$1" "${1//:/-}"'によって生成された内部シェルはbash -cinという名前を受け取り、その名前に展開され$1ています。${1//:/-}:-

(コマンドの末尾にある尾はサブシェルにbash提供されるものです。)$0bash -c

関連情報