ファイルの名前を変更して拡張子を変更し、効果的に達成したい
mv *.txt *.tsv
しかし、これを行うと次のようになります。
* .tsvはディレクトリではありません
最初の10件のGoogleヒットがmv
がこのように機能することを示すのは少し変だと思います。
コマンドを発行すると:
mv *.txt *.tsv
シェル、bashと仮定しましょう、expandsワイルドカードif一致するファイルがあります(ディレクトリを含む) )。ファイルのリストがプログラムに渡されます。ここではmv
です。一致が見つからない場合は、展開されていないバージョンが渡されます。
繰り返しますが、Shellはプログラムではなくパターンを展開します。
例の負荷はおそらく最良の方法なので、ここに行きます:
$ 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
代わりに言うなら:
$ mv *1.txt *.tsv
mv
コマンドは次のコマンドで実行されます。
argc = 3
argv[0] = mv
argv[1] = file1.txt
argv[2] = *.tsv
ここでも、mv
をチェックして、*.tsv
が存在するかどうかを確認します。そうではないので、ファイルfile1.txt
は*.tsv
に移動されます。つまり、ファイル名は*.tsv
に変更され、アスタリスクとすべてが追加されます。
$ mv *1.txt *.tsv
‘file1.txt’ -> ‘*.tsv’
$ ls
file2.txt *.tsv
あなたが代わりに言った場合:
$ 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"
と言います。
たとえば、次のようにすると、展開をさらに表示できます。
$ ls
file1.txt file2.txt
$ mkdir *.txt
mkdir: cannot create directory ‘file1.txt’: File exists
mkdir: cannot create directory ‘file2.txt’: File exists
今:mv
コマンドは、複数のファイルを処理できます。ただし、2つ以上ある場合は、最後がターゲットディレクトリでなければなりません。 (オプションで、少なくともGNU mv。の場合、-t TARGET_DIR
オプションを使用できます。)
これは問題ありません:
$ 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
に置かれます。
あなたのリンクについても。コメントで1つ提供しましたが、mv
はまったく言及されていませんが、rename
は言及されています。あなたがより多くのリンクを共有することができるなら。これが表現されていると主張するマニュアルページも同様です。
これであなたの質問に答えられないのはわかっていますが、回避策のループと比較してファイルの名前を変更する別の方法を探していた場合は、find
を使用しないでください。このコマンドを何度も使用して、大規模なディレクトリのファイル拡張子を数十万のファイルに置き換えました。これは、POSIX準拠のシステムで機能します。
find . -name "*.gappedPeak" -exec sh -c 'mv "$1" "${1%.gappedPeak}.bed"' _ {} \;
コマンドの内訳:
'
.
' => 'でマークされた現在のディレクトリから始まる検索パス」
-name
=>検索一致名を設定(この場合、.gappedPeak
で終わるすべてのファイル)
-exec
=>すべての一致で次のコマンドを実行します
sh -c
=> 'exec'は、一致ごとに独立したシェル環境を作成します
mv "$1" "${1%.gappedPeak}.bed"
=>mv
現在のファイル名である最初の変数($ 1で示される)を新しい名前に変更します。ここで、部分文字列の一致と削除を行います。したがって、最初の変数$ 1を再度取得し、%
を使用して文字列から.gappedPeak
を削除します。最後の.bed
は、残りの変数(現在はtest#
)を.bed
と連結して、新しいtest#.bed
ファイル名を作成します。下線は$のプレースホルダーです
{}
は、find
コマンドで検出された各(*.gappedPeak
)ファイル名に置き換えられ、_$ 1からsh
コマンドになります。
\;
は、-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
mv *.txt *.tsv
機能しません。 mv
は、一度に1つのファイルのみ名前を変更できます。説明を誤解しているか、説明が間違っています。
mmv
およびrename
は、一度に複数のファイルの名前を変更できます。ただし、rename
には、異なる方法で呼び出される2つのバージョンがあります。これについては、たくさんの質問があるはずです。
たとえば、asd.txt
コマンドを実行すると、ディレクトリにqwe.txt
ファイルとmv *.txt *.tsv
ファイルがある場合、これら2つのファイルを*.tsv
という名前のディレクトリに移動しようとします。そのようなディレクトリがないため、エラーが発生します。
rename(1)
rename
は、Perlの作成者であるLarry WallによるPerlスクリプトです。 Perlの正規表現を使用して、ファイル名を操作します。
rename 's/\.txt$/.tsv/' *.txt
Debian/Ubuntuにrename
をインストールする必要がある場合は、次のことができます
Sudo apt install rename
考慮すべきもう1つのオプションは、次のものを使用することです。
cp -p *.txt *.tsv
rm -f *.txt
*.txt
フラグを使用して属性を保持しながら、すべての*.tsv
ファイルを-p
にコピーします。*.txt
のすべてのファイルを削除しますmv
よりも遅く、ファイルが別のパーティションにない限り、実際にはファイルを移動せずに/ directory/filenameを変更するだけです。