拡張子を変更するには、mvを使用して複数のファイルの名前を変更します。

拡張子を変更するには、mvを使用して複数のファイルの名前を変更します。

拡張子を変更するためにファイル名を変更したいと思います。効果的に完了しようとしています。

mv *.txt *.tsv

しかし、これを行うと、次のような結果が得られます。

*.tsv はディレクトリではありません。

mv最初の10回のGoogleクリックマークがこのように機能することが少し奇妙だと思います。

答え1

これがあなたの質問に対する答えではないことを知っていますが、回避策ループではなくファイル名を変更する別の方法を探している場合はfind?私は何十万ものファイルを含む大規模ディレクトリのファイル拡張子を置き換えるためにこのコマンドを複数回使用しました。これはすべてのPOSIX互換システムで機能します。

find . -name "*.gappedPeak" -exec sh -c 'mv "$1" "${1%.gappedPeak}.bed"' _ {} \;

コマンド分析:

  1. '.'=>' で示される現在のディレクトリから始まる検索パス。 '

  2. -name=>照会一致名の設定(この場合で終わるすべてのファイル .gappedPeak

  3. -exec=> 各ゲームで次のコマンドを実行します。

  4. sh -c=> 'exec'はゲームごとに別々のシェル環境を作成します。

  5. mv "$1" "${1%.gappedPeak}.bed"=>mv最初の変数(次のように表現されます)1)(現在のファイル名)が新しい名前に変更されます。ここでは部分文字列のマッチングを実行して削除するので、最初のvarを再取得します。1文字列から削除するために使用されます%.gappedPeak最後の.bed変数は、残りの変数(以下の例では、)を連結して新しいファイル名を作成します。testNumber.bedtestNumber.bed

  6. 下線はプレースホルダです。$0

  7. {}は、コマンドで見つかった*.gappedPeak各()ファイル名に置き換えfindられます。1shコマンドに。

  8. \;コマンドの終わりを表示します-exec';'またはを使用することもできます";"

例:

[user@before]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.gappedPeak

[user@after]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.bed

答え2

この答えは、拡張を変更するのには役に立ちませんが、コマンドが期待どおりに実行されない理由を理解するのに役立ちます。

コマンドを実行すると、次のようになります。

mv *.txt *.tsv

シェル、bashを仮定しましょう。拡大するワイルドカードもし一致するファイル(ディレクトリを含む)があります。ファイルのリストはここからプログラムに渡されますmv。一致するものがない場合、拡張されていないバージョンが渡されます。

再:シェルプログラムではなく拡張モードです。


多くの例は、おそらくこれがうまくいかない理由を理解するための最良の方法です。それでは始めましょう。

例1:

$ ls
file1.txt file2.txt

$ mv *.txt *.tsv

mv今オンラインで起こっていることはシェル*.txt一致するファイルに展開します。変更されていないファイルがないためです*.tsv

コマンドmvが呼び出されます。2つの特別なパラメータがあります。:

  • argc:プログラムを含むパラメータの数。
  • argv: プログラムを最初の項目として含む引数の配列。

上記の例では、次のようになります。

 argc = 4
 argv[0] = mv
 argv[1] = file1.txt
 argv[2] = file2.txt
 argv[3] = *.tsv

プログラムmvは最後の引数がディレクトリ*.tsvであることを確認します。そうしないと、ファイル接続用に設計されていないため、プログラムを続行できません。 (すべてのファイルを1つにまとめます。)また、任意にディレクトリを作成することはできません。

その結果、エラーが中断され、報告されます。

mv: target ‘*.tsv’ is not a directory

例2:

さて、次のように言うと:

$ mv *1.txt *.tsv

コマンドmvは次のように実行されます。

 argc = 3
 argv[0] = mv
 argv[1] = file1.txt
 argv[2] = *.tsv

今存在mvすることを再確認してください*.tsv。何もなかったので、ファイルは.iefile1.txtに移動されました*.tsv。ファイル名は*.tsvアスタリスクとすべてに変更されました。

$ mv *1.txt *.tsv
‘file1.txt’ -> ‘*.tsv’

$ ls
file2.txt *.tsv

例3:

代わりに、次のように言った場合:

$ mkdir *.tsv
$ mv *.txt *.tsv

コマンドmvは次のように実行されます。

 argc = 3
 argv[0] = mv
 argv[1] = file1.txt
 argv[1] = file2.txt
 argv[2] = *.tsv

*.tsvこれがディレクトリなので、ファイルは最終的にそのディレクトリに移動されます。


これで、インテントが実際にワイルドカードを保持している場合などのコマンドを使用する場合は、some_command *.tsv常に引用する必要があります。引用符を使用すると、一致するものがある場合にワイルドカードが拡張されるのを防ぐことができます。たとえばmkdir "*.tsv"

例4:

これにより、次の拡張機能の詳細を確認できます。

$ ls
file1.txt file2.txt

$ mkdir *.txt
mkdir: cannot create directory ‘file1.txt’: File exists
mkdir: cannot create directory ‘file2.txt’: File exists

例5:

これで、このmvコマンドは複数のファイルで動作でき、動作します。ただし、2つ以上の場合は、最後のディレクトリがターゲットディレクトリである必要があります。 (-t TARGET_DIR少なくともGNU mvでは、このオプションを使用することを選択できます。)

だからこれは大丈夫です:

$ ls -F
b1.tsv  b2.tsv  f1.txt  f2.txt  f3.txt  foo/

$ mv *.txt *.tsv foo

これは次mvのように呼び出されます。

 argc = 7
 argv[0] = mv
 argv[1] = b1.tsv
 argv[2] = b2.tsv
 argv[3] = f1.txt
 argv[4] = f2.txt
 argv[5] = f3.txt
 argv[6] = foo

すべてのファイルはディレクトリに保存されますfoo


あなたのリンクは。あなたはmvまったく言及されていないものを(コメントに)提供しましたrename。しかし、あなたの主張を表現する共有できるリンクやマニュアルページはありますか?

答え3

mv *.txt *.tsv動作しません。mv一度に1つのファイルのみ名前を変更できます。あなたはこれらの説明を誤解したか間違っていました。

mmv一度に複数のファイルの名前を変更できますrename。ただし、aroundrenameにはさまざまな方法で呼び出される2つのバージョンがあります。ここに多くの質問があるはずです。

答え4

たとえば、コマンドを実行するときにディレクトリにファイルがある場合、asd.txt2つのファイルを名前付きディレクトリに移動しようとします。そのディレクトリがないため、エラーが報告されます。qwe.txtmv *.txt *.tsv*.tsv

関連情報