サブディレクトリのファイル名のドットを削除したい。 rename
とfind
を使用します。
find . -type f -name '*.avi' -exec rename 's/\.(?=[^.]*\.)/ /g' {} \;
コマンドfind
は単独で機能します。コマンドrename
は単独で機能します。しかし、両方を一緒に使用すると、エラーが発生します。
No such file or directory
それらを一緒に機能させる方法は?
私はこれをテストしましたが、機能しません:
mkdir test
cd test
mkdir f1
cd f1
touch {1..20}-file.with.dot.avi
cd ..
cp -r f1/ f2
cd ..
find . -type f -name '*.avi' -exec rename 's/\.(?=[^.]*\.)/ /g' "{}" \;
私はこれをテストしますが、動作しません
mkdir test
cd test
mkdir f1
cd f1
touch {1..20}-file.with.dot.avi
cd ..
cp -r f1/ f2
cd ..
find . -type f -name '*.avi' -exec rename 's/\.(?=[^.]*\.)/ /g' "{}" \;
注 多くのrename
sがあります 。 OPのrename
はPerlrename
(prename
と呼ばれることもあります)のようです。一般に、rename
Perl rename
を実行する場合と実行しない場合があります 。
エラーは次のようなものです。
_Can't rename ./test/f1/1-file.with.dot.avi /test/f1/1-file with dot.avi: No such file or directory
_
ターゲットパスが意味をなさないことに注意してください。絶対的に見えますが、実際には_/
_で始まりません。スペース文字で始まります。これは、先頭のドット(_.
_)がスペース文字に置き換えられたためです。ディレクトリ_<space>/test/f1/
_はなく、rename
はそれを作成しないため、_No such file or directory
_。
find
は、ユーザーが指定したパスの1つでパス名を開始する必要があり、パスとして_.
_を指定したため、ドットがありました。
いくつかの解決策があります:
開始パスとして_.
_を使用しないでください。例えば。:
_find "$PWD" -type f -name '*.avi' -exec rename 's/\.(?=[^.]*\.)/ /g' {} \;
_
ディレクトリ名(_$PWD
_が展開されるディレクトリまたはその下のディレクトリ)にドットがある場合は、同じ問題が発生する可能性が高いことに注意してください。
欠落しているドットを再度追加します。
_find . -type f -name '*.avi' -exec rename 's/\.(?=[^.]*\.)/ /g; s/^ /./' {} \;
_
これは一般的な解決策ではありません。繰り返しますが、パス名に_.
_のディレクトリコンポーネントが含まれている場合は、問題が発生する可能性があります。
find
が_-execdir
_をサポートしている場合は、それを使用してください。結果のパス名は_./1-file.with.dot.avi
_のようになり、ディレクトリ名のドットは無関係になります。それでも、この主要なドットに対処する必要があります。例:
_# re-adding dot like in the above approach
find . -type f -name '*.avi' -execdir rename 's/\.(?=[^.]*\.)/ /g; s/^ /./' {} \;
# or stripping ./ first
find . -type f -name '*.avi' -execdir rename 's|^\./||; s/\.(?=[^.]*\.)/ /g' {} \;
_
利用できない場所で_-execdir
_をエミュレートするPOSIXソリューションでは、シェルを実行する必要があります。可能なアプローチ:
_find . -type f -name '*.avi' -exec sh -c '
cd "$(dirname "$2")" && rename "$1" "$(basename "$2")"
' find-sh 's/\.(?=[^.]*\.)/ /g' {} \;
_
ノート:
rename
自体はPOSIXツールではありません。s/\.(?=[^.]*\.)/ /g
を別の引数としてsh
に渡すことを選択しました。これは、単一引用符で囲まれたシェルコードに埋め込んで、引用符を適切にネストすることを心配するのではありません。式を改善して、ディレクトリコンポーネント(先頭のドットを含む)を変更せず、ファイル名(パス名の最後の_/
_の後の文字列)のみを変更します。私はこれを助けるために正規表現で十分ではありません。