電子メールファイル名を.txtから.emlに繰り返し変更します。

電子メールファイル名を.txtから.emlに繰り返し変更します。

"$d"ディレクトリには、.txt拡張子を持つ何千もの電子メールファイルが含まれています。電子メールクライアントで開くには、名前を.emlに変更する必要があります。

このコマンドは名前を正しく変更しますか?

find "${d}" -type f -name '*.txt' | while read f; do mv -vn "${f}" "${f%.*}".eml; done

それともこれを行うより良いより強力な方法がありますか?

私はエレガントな使い方を考えることはできません。

-exec ...{}... \;

答え1

あなたの解決策は通常大丈夫ですが、改行のために中断されます。以下は少し強力なbash4+ソリューションです。

shopt -s globstar nullglob
for file in **/*.txt; do
    mv "$file" "${file%.*}.eml"
done

答え2

私の考えでは、あなたは大丈夫だと思います。

find "$d" -name \*.txt -exec rename .txt .eml {} \;

でも

for f in *.txt; do rename .txt .eml "$f"; done

すべてのファイルが同じディレクトリにある場合。

答え3

bashはい、同様の構文のシェルを使用すると仮定すると、コマンドは機能します。将来的には、このような大規模なコマンドの使用を検討する際に、echoコマンドラインを使用して結果をプレビューできることに注意してください。つまり、前に置いてechoパイプmvラインを実行して、コマンドが何であるかを確認できます。よかったら、削除しechoて実際にコマンドを実行してください。

答え4

zshではzmvこれを簡単にしてください。autoload -U zmvyours を入力し~/.zshrcた後、いくつかの方法のいずれかを使用して、**/*.txt現在のディレクトリとサブディレクトリの拡張子を持つファイルと一致する代替テキストを指定します。txt

zmv '**/*.txt' '$f:r.eml'
zmv '**/*.txt' '${f%.*}.eml'
zmv '(**/)(*).txt' '$1$2.eml'
zmv -w '**/*.txt' '$1$2.eml'

zshはありませんが、bash ≥4またはksh93がある場合は、**再帰を使用してサブディレクトリを巡回してから一致を繰り返すことができます。 bash(あなたのものに入れてください)またはksh(あなたのものに入れてください)を使って**最初にglobモードを有効にする必要があります。これはzshでも機能します(プリセットは必要ありません)。shopt -s globstar~/.bashrcset -o globstar~/.kshrc

for f in **/*.txt; do mv -- "$f" "${f%.*}.eml"; done

これにより、通常のファイルだけでなくすべてのファイルの名前が変更されます。ディレクトリやその他の非正規ファイルがあり、それを変更せずに保持したい場合:

zmv -Q '**/*.txt(.)' '$f:r.eml'
for f in **/*.txt; do [[ -f $f ]] && mv -- "$f" "${f%.*}.eml"; done

POSIXの外部にはシェル機能がないため、findサブディレクトリを参照するには呼び出す必要があります。バックスラッシュ、末尾の空白、または改行を含むファイルでは、ソリューションが破損するため脆弱です。次のコマンドを使用して、末尾のスペースとバックスラッシュの問題を解決できます。while IFS= read -r f; do …しかし、パイプで接続された出力はfind本質的に改行で中断されます。代わりに使用してください-exec。 Linuxではこのユーティリティを使用できますrenameディストリビューションに付属しているものは何でも)。 Debian、Ubuntu、およびその派生物:

rename 's/\.txt$/.eml/' **/*.txt
find . -name '*.txt' -type f -exec rename 's/\.txt$/.eml/' {} +

.txt他のディストリビューションでは、中間にファイル名がない限り(renameソース文字列の最初のエントリが置き換えられるため):

rename .txt .eml **/*.txt
find . -name '*.txt' -type f -exec rename .txt .eml {} +

プロセス全体でPOSIX機能のみが使用され、名前変換を実行するためにシェルを呼び出します。

find . -name '*.txt' -type f -exec sh -c 'for f; do mv "$f" "${f%.*}.eml"; done' _ {} +

findをサポートするには、バージョンが古すぎる場合は、-exec … +各ファイルに対してシェルを呼び出す必要があります。これにより、コードが簡単になりますが、遅くなります。

find . -name '*.txt' -type f -exec sh -c 'mv "$0" "${0%.*}.eml"; done' {} \;

関連情報