複数のファイルの拡張子を変更するにはどうすればよいですか?


168

ファイル拡張子をから*.txtに変更したいと思います*.textbasenameコマンドを使用してみましたが、複数のファイルを変更するのに問題があります。

これが私のコードです:

files=`ls -1 *.txt`

for x in $files
do
    mv $x "`basename $files .txt`.text"
done

私はこのエラーを受け取っています:

basename: too many arguments Try basename --help' for more information

で、いくつかのアイデアpeteryu.ca/tutorials/shellscripting/batch_renameすぎ
ニモ

回答:


176

GregのWikiから直接

#すべての* .txtの名前を* .textに変更
* .txtのf 行う
    mv-"$ f" "$ {f%.txt} .text"
やった

また、解析しないls理由のエントリも参照してください。

編集:basename構文を使用する必要がある場合:

* .txtのf 行う
    mv-"$ f" "$(basename-" $ f ".txt).text"
やった

48
ここでは、説明なしで少し高度なBash構文を使用しています。これを完全に理解するために、私は多くのことをGoogleに求めました。私の立場にある他の人を助けるために、glob(*.txt構文)裸の二重ダッシュ--、および構造内での%記号の使用${}に関する参照をいくつか示します。今まで私は後者の2つに出会うことはなく、前者で実際に何が起こっているのか知らなかった。
マークアメリー14

3
以下のMatthias Braunの答えを見てください-もっと簡単に、同じことを達成します。
btk

10
1つのライナーfor f in *.txt; do mv -- "$f" "${f%.txt}.text"; done
マルサルフアン

1
不足している; 「テキストの後。
PéturIngi Egilsson

2
2行目の@PéturIngiEgilsson?いいえ、必須ではありません。
-jasonwryan

132

Debianの現在のディレクトリにあるすべてのファイル拡張子を変更する方法は次のとおりです。

rename "s/oldExtension/newExtension/" *.txt

(これはPerl renameコマンドであり、util-linux1つではありません。Debian/ Ubuntuの名前変更ユーティリティがCentOSなどの他のディストリビューションのユーティリティと異なるのはなぜですか?を参照してください


10
受け入れられた答えよりもはるかに簡単です、ありがとう!
btk

8
Macではbrew install rename、これを機能させることができました。
モンクピット

3
魚のシェルにあなたが行うことができますrename "s/oldExtension/newExtension/" **.txt名前を変更するために、すべての*は、再帰的に.TXT
Palmstrom

3
これは失敗しfootxt.txtます。代わりにこれを使用します。unix.stackexchange.com/questions/19654/...を
wisbucky

7
ファイルに拡張子がなく、拡張子を追加する場合:rename 's/$/.txt/' *
-mkataja

35

単純なコマンドrenamefromutil-linuxは、それを行います。「*。txt」に一致するすべてのファイルで、「txt」が出現するたびに「text」に置き換えます。

rename txt text *.txt

4
rename最初のオカレンスを変更するので、それをより適切に作成しますrename .txt .textが、これは常に機能するとは限りません(たとえば、名前foo.txtx.bar.txtをに変更しますfoo.textx.bar.txt)。
ジル

12
すべてのシステムに同じバージョンの名前変更があるわけではないことに注意してください。Debianや友人では、renameコマンドは実際perl-renameにはperlの正規表現を使用しています。そのため、同等のコマンドは次のようになりますrename 's/.txt/.text/' *.txt。人々はman rename自分のシステムをチェックして、自分が持っているものを見つける必要があります。
evilsoup

@evilsoupそれはOSX、THXのためのケースだ
ダヴィリマ

これはCygwin(Windows)でも動作します
-andy

27
rename "s/oldExtension/newExtension/" *.txt

上記は正常に機能しますが、現在のディレクトリに限定されます。以下のコマンドを試してください。これは、サブディレクトリに対して柔軟です。.txtディレクトリ構造下のすべてのファイルの名前を新しい拡張子に変更します。

find . -name "*.txt" -exec rename 's/.txt$/.newext/' {} \;

2
rename引数として複数のファイルを処理できる場合、そのようなファイルが多数+ある\;場合の代わりに使用することにより、物事を大幅に高速化できます
-Anthon

それでも、「*。txt」はシェルでサポートされていない大きな引数リストに展開できるため、便利なオプションです。
ローマンシャポバロフ

1
「s / oldExtension / newExtension /」は失敗しfootxt.txtます。:この代わりに使用しunix.stackexchange.com/questions/19654/...を
wisbucky


9

ここで参照s/oldExtension/newExtension/する答えは間違っています。を使用s/txt/text/するfootxt.txtfootext.txt、に変換されますが、これは望みのものではありません。使用してもs/.txt/.text/、それはに変換さfootxt.txtfo.text.txtます。

\.ピリオドを一致させるために使用する必要があります(.任意の文字と一致します)。そして、$行の終わりに一致する末尾。これだけが拡張子に適切に一致します。

rename 's/\.txt$/.text/' *.txt

rename 's/\.old$/.new/' *.old

7

@Princeジョン・ウェズリーの回答に基づいて、ここから現在のディレクトリ内のすべてのファイルの拡張子を変更するための簡単なbashスクリプトであるext1ext2。また、名前を変更するファイルの名前を出力します。

#!/bin/bash
for f in *.$1
do
    [ -f "$f" ] && mv -v "$f" "${f%$1}$2"
done

使用例(スクリプトの名前がであると仮定change-ext):

change-ext ext1 ext2

再帰的にディレクトリ内のファイルの拡張子を変更するには、二行目を(置き換えるfor...2行):shopt -s globstarfor f in **/*.$1。Bash 4+が必要です。
デニスゴロマゾフ


3

ファイルがさまざまなディレクトリに散らばっているとしましょう。dirxが親ディレクトリであると仮定すると、findを使用してジョブを実行できます。

for f in `find /dirx -iname '*.txt' -type f -print`;do  mv "$f" ${f%.txt}.text; done

tcshのはどう...
ヨーゼフKlimuk


2

あなたが

ソースファイルの拡張子がありません

ターゲットの拡張子は.textで、この方法で実行します -

for f in *; do mv -- "$f" "${f%.\*}.text"; done

1
優れたbashネイティブスクリプト。うまくいきました!for f in *.html; do mv -- "$f" "${f%.\*}.pug"; done
TamusJRoyce

1

あなたのバージョンで何がうまくいかなかったか知りたい場合:basenameコマンドの$files代わりに使用し$xました。したがって、これは動作するはずです(ただし、テストされていません):

for x in *.txt
do
  mv "$x" "`basename '$x' .txt`.text"
done
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.