.abc
拡張子を持つ多くのファイルがあり、それらを.edefg
に変更したい
コマンドラインからこれを行う方法
ルートフォルダーには多くのサブフォルダーがあるため、ソリューションは再帰的に機能します。
ポータブルな方法(POSIX準拠のシステムで動作します):
find /the/path -depth -name "*.abc" -exec sh -c 'mv "$1" "${1%.abc}.edefg"' _ {} \;
Bash4では、globstarを使用して再帰的なグロブ(**)を取得できます。
shopt -s globstar
for file in /the/path/**/*.abc; do
mv "$file" "${file%.abc}.edefg"
done
Ubuntuの(Perl)rename
コマンドは、Perlの正規表現構文を使用してファイルの名前を変更できます。これは、globstarまたはfind
と組み合わせることができます。
# Using globstar
shopt -s globstar
files=(/the/path/**/*.abc)
# Best to process the files in chunks to avoid exceeding the maximum argument
# length. 100 at a time is probably good enough.
# See http://mywiki.wooledge.org/BashFAQ/095
for ((i = 0; i < ${#files[@]}; i += 100)); do
rename 's/\.abc$/.edefg/' "${files[@]:i:100}"
done
# Using find:
find /the/path -depth -name "*.abc" -exec rename 's/\.abc$/.edefg/' {} +
http://mywiki.wooledge.org/BashFAQ/0 も参照してください
すべてのファイルが同じフォルダーにある場合、これは必要なタスクを実行します
rename 's/.abc$/.edefg/' *.abc
ファイルの名前を再帰的に変更するには、次を使用します。
find /path/to/root/folder -type f -name '*.abc' -print0 | xargs -0 rename 's/.abc$/.edefg/'
再帰的な名前変更の問題の1つは、ファイルの検索に使用する方法が何であれ、ファイル名だけでなくrename
にパス全体を渡すことです。そのため、ネストされたフォルダーで複雑な名前の変更を行うのが難しくなります。
この問題を解決するには、find
の-execdir
アクションを使用します。 -execdir
の代わりに-exec
を使用する場合、指定されたコマンドは、一致したファイルを含むサブディレクトリから実行されます。したがって、パス全体をrename
に渡すのではなく、./filename
のみを渡します。これにより、正規表現を簡単に記述できます。
find /the/path -type f \
-name '*.abc' \
-execdir rename 's/\.\/(.+)\.abc$/version1_$1.abc/' '{}' \;
詳細に:
-type f
は、ディレクトリではなくファイルのみを検索することを意味します-name '*.abc'
は、.abcで終わるファイル名のみに一致することを意味します-type
および-name
の後のバックスラッシュは、bashの行継続文字です。これらを使用してこの例を読みやすくしますが、実際には必要ありません。-execdir
行の最後にバックスラッシュが必要です。セミコロンをエスケープするためにあり、-execdir
によって実行されたコマンドを終了します。楽しい!正規表現の説明:
s/
正規表現の開始\.\/
は、-execdirが渡す先頭の./と一致します。\を使用して、。および/メタキャラクター(.+)
はファイル名と一致します。括弧は、後で使用するために一致をキャプチャします\.abc
はドットをエスケープし、abcと一致します$
文字列の最後に一致を固定します
/
は、正規表現の「一致」部分の終わりと「置換」部分の始まりを示します
version1_
このテキストをすべてのファイル名に追加します
$1
は、括弧でキャプチャしたため、既存のファイル名を参照します。 「一致」部分で括弧の複数のセットを使用する場合、$ 2、$ 3などを使用してここでそれらを参照できます。.abc
新しいファイル名は.abcで終わります。ここで「置換」セクションでドットメタキャラクターをエスケープする必要はありません。/
正規表現の終わり前
tree --charset=ascii
|-- a_file.abc
|-- Another.abc
|-- Not_this.def
`-- dir1
`-- nested_file.abc
後
tree --charset=ascii
|-- version1_a_file.abc
|-- version1_Another.abc
|-- Not_this.def
`-- dir1
`-- version1_nested_file.abc
ヒント:rename
の-nオプションは便利です。ドライランを実行し、変更する名前を表示しますが、変更は行いません。
別のポータブルな方法:
find /the/path -depth -type f -name "*.abc" -exec sh -c 'mv -- "$1" "$(dirname "$1")/$(basename "$1" .abc).edefg"' _ '{}' \;
# Rename all *.txt to *.text
for f in *.txt; do
mv -- "$f" "${f%.txt}.text"
done
ls
を解析しない理由のエントリも参照してください。
編集:basenameを使用する必要がある場合、構文は次のようになります。
for f in *.txt; do
mv -- "$f" "$(basename "$f" .txt).text"
done
https://unix.stackexchange.com/questions/19654/changing-extension-to-multiple-files
これを実現する簡単な方法を見つけました。多くのファイルの拡張子をjpgからpdfに変更するには、次を使用します。
for file in /path/to; do mv $file $(basename -s jpg $file)pdf ; done
これが私がしたことであり、私が望んでいた通りに機能しました。 mv
コマンドを使用しました。複数の.3gp
ファイルがあり、それらをすべて.mp4
に名前変更したかった
以下に短いワンライナーを示します。
for i in *.3gp; do mv -- "$i" "ren-$i.mp4"; done
単に現在のディレクトリをスキャンし、すべての.3gpファイルを取得し、(mvを使用して)名前をren-name_of_file.mp4
に変更します
同じ名前のパッケージ から mmvコマンド を使用します。
mmv ';*.abc' '#1#2.edefg'
;
は0個以上の*/
と一致し、置換の#1
に対応します。 *
は#2
に対応します。非再帰バージョンは
mmv '*.abc' '#1.edefg'