次のコマンドを使用して、特定のサブフォルダのファイル名にあるすべてのコロンをダッシュに置き換えようとしました。
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
か、時には別のものとして呼び出されます。prename
rename
これがコマンドラインから期待するものです。
rename
そして、その有用性は非常に限られていますutil-linux
。これはrename.ul
一部のシステムで呼び出されることがあります。rename
perl
rename
この文字列を使用すると、ある文字列を別の文字列にのみ置き換えることができます。これは可能ですが、-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}
できます)。bash
ksh
zsh
bash
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 -c
inという名前を受け取り、その名前に展開され$1
ています。${1//:/-}
:
-
(コマンドの末尾にある尾はサブシェルにbash
提供されるものです。)$0
bash -c