Returnキーを押す前に誤って宛先を指定するのを忘れました。どこでやる mv ./*
移動先を指定せずに、現在のディレクトリの下のファイルとディレクトリを移動しますか?
最後の引数がディレクトリの場合は、現在の作業ディレクトリ内のすべてのファイルとディレクトリ(名前がドットで始まるものを除く)をそのディレクトリに移動しただけです。 2つのファイルがあった場合、最初のファイルが2番目のファイルを上書きした可能性があります。
ここにいくつかのデモンストレーションがあります:
つ以上のファイル、最後の引数はファイル
$ mkdir d1 d2 d3
$ touch a b c e
$ mv *
mv: target 'e' is not a directory
つ以上のファイル、最後の引数はディレクトリ
$ mkdir d1 d2 d3
$ touch a b c
$ mv -v *
'a' -> 'd3/a'
'b' -> 'd3/b'
'c' -> 'd3/c'
'd1' -> 'd3/d1'
'd2' -> 'd3/d2'
2つのファイル
$ touch a b
$ mv -v *
'a' -> 'b'
詳しい説明
シェルはグロブ(*
)をmv
の引数に挿入します。グロブは通常、アルファベット順に展開されます。 mv
は常にファイルとディレクトリのリストを参照します。グロブ自体を見ることはありません。
コマンドmv
は、2種類の移動をサポートしています。 1つはmv file ... directory
。もう1つはmv old-file-name new-file-name
(またはmv old-file-name directory/new-file-name
)。
まず、テストベースを作成します-5つのファイルと1つのフォルダー:
_touch file1 file2 file3 file4 file5
mkdir folder
_
次に、テストコマンドを実行します。 _-v
_オプションは、シェルが実行するすべてのコマンドをstderr
に出力することを指定します。 _-x
_オプションは、同じものをstderr
に出力することを指定します-but実行したいafterコマンドは評価されますが、beforeシェルがそれを実行します。
_sh -cxv 'echo mv *'
_
_echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder
_
シェルにフィードするコマンドは_echo mv *
_であり、シェルが実行するコマンドはafter_*
_が展開された_echo mv
_の後に続くそれらすべてのファイルとフォルダ。
デフォルトでは、シェルはglobsを次のように展開します:
_sh -cxv 'echo file[1-5]'
_
_echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5
_
これは_set [+-]f
_グロブ関数の結果です:
_sh -cxvf 'echo file[1-5]'
_
_echo file[1-5]
+ echo 'file[1-5]'
file[1-5]
_
したがって、_mv *
_のようなデフォルトのオプションで構成されたシェルでコマンドを実行すると、シェルは_*
_ Wordに展開され、現在のディレクトリ内のすべてのファイルの引数リストがロケールに従ってソートされます。これは、mv
に対してsyscall exec(ve)
を実行します(基本的に)この引数リストが追加されます。したがって、mv
は、シェルがそれらをグロブしてソートするときにすべての引数を取得します。これらの効果を確認するためにstrace
を実行する以外に、次のようにデバッグを再度使用できます。
_sh -s -- mv * <<\SCRIPT
sed -n l /proc/$$/cmdline
echo "$@"
SCRIPT
_
_sh\000-s\000--\000mv\000file1\000file2\000file3\000file4\000file5\000folder\
\000$
mv file1 file2 file3 file4 file5 folder
_
そして移植性:
_( PS4= IFS=/; set -x mv *; : "/$*/" ) 2>&1
_
_: /mv/file1/file2/file3/file4/file5/folder/
_
基本的に、シェルはディレクトリのコンテンツを使用してmv
を実行します(空ではなく、_.
_で始まる名前のファイル/フォルダーが含まれていない場合)を引数リストとして。 mv
は、2つ以上の引数で呼び出された場合、最後の引数をディレクトリとして解釈するように指定されたPOSIXです。同じ方法でln
はです(実際、 、それらは基礎となる機能において非常に類似したツールです)。
十分なecho
esただし:
_sh -cxv 'mv *' ; ls
_
_mv *
+ mv file1 file2 file3 file4 file5 folder
folder/
_
すべてのファイルは最後の引数に移動されました。これはフォルダーであるためです。次に、それがフォルダでない場合はどうなりますか?
_sh -cxv 'cd *; mv *'; ls . *
_
_cd *; mv *
+ cd folder
+ mv file1 file2 file3 file4 file5
mv: target ‘file5’ is not a directory
.:
folder/
folder:
file1 file2 file3 file4 file5
_
これが POSIXが指定するmv
がその場合に動作する方法です。
_mv [-if] source_file target_file
mv [-if] source_file... target_dir
_
最初の概要形式では、
mv
ユーティリティは、source_fileオペランドで指定されたファイルをtarget_fileで指定された宛先に移動します。この最初の構文形式は、最後のオペランドが既存のディレクトリを指定しておらず、既存のディレクトリを参照するシンボリックリンクでない場合に想定されます。この場合、source_fileが非ディレクトリファイルを指定し、target_fileが末尾の_/slash
_文字で終了する場合、mv
はこれをエラーとして扱い、source_fileオペランドは処理されません。2番目の形式では、
mv
は、source_fileオペランドで指定された各ファイルを、target_dirオペランドで指定された既存のディレクトリ内の宛先ファイルに移動します。 target_dirは、既存のディレクトリを参照するシンボリックリンクです。各source_fileの宛先パスは、ターゲットディレクトリの連結、ターゲットが_/slash
_で終わっていない場合は単一の_/slash
_文字、およびソースファイル。この2番目の形式は、最後のオペランドが既存のディレクトリを指定する場合に想定されます。
したがって、_*
_が次のように展開される場合:
2つのファイル
renamed
から2番目のファイルがunlinked
までのファイルは1つだけです。1つ以上のファイルの後にディレクトリまたは1つのファイルへのリンクが続く
他に何か
最初にシェルが展開します./*
現在のディレクトリ内のすべてのファイル(ドットで始まるファイルを除く)。
mv
は失敗しますmv
は失敗します。mv ./*
と入力すると、シェルはmv
を実行する前に./*
を展開します。
注意すべきいくつかの事柄:
./*
が2つ未満の引数に展開される場合、mv
は論理的にはエラーを生成します。./*
は通常、現在のディレクトリに存在し、ドットで始まっていないすべてのファイル(ディレクトリを含む)に展開されます。./*
の展開対象を制御できます(man 7 glob
はトピックへのエントリポイントです)。シェルが異なれば、オプションも異なります。
mv *
の機能
ここに短い答えがあります:
シェルはワイルドカード*
をディレクトリの内容のリストに展開します。次に、シェルはその完全なリストをコマンドに渡します。コマンドは*
を見ることはありません。
コマンドmv file1 file2 ... filen directory
は、file1 ... filenをディレクトリに移動します。
ここでは、3つのファイルを含むテストディレクトリを作成します。
$ mkdir t
$ cd t
$ echo a>a; echo b>b; echo c>c
$ ls
a b c
複数のファイルを1つのファイルに移動することはできません
$ mv *
mv: target `c' is not a directory
サブディレクトリを追加しましょう
$ mkdir d
複数のファイルをサブディレクトリに移動することができます
$ mv *
$ ls
d
$ ls d
a b c