ターゲットを指定せずに `mv ./*` は何をしますか?

ターゲットを指定せずに `mv ./*` は何をしますか?

誤ってEnterキーを押す前に目的地を指定することを忘れていました。mv ./*ターゲットを指定せずに現在のディレクトリのファイルとディレクトリをどこに移動しますか?

答え1

最後の引数がディレクトリの場合は、現在の作業ディレクトリ(名前がドットで始まるファイルを除く)のすべてのファイルとディレクトリをそのディレクトリに移動します。 2つのファイルがある場合、最初のファイルは2番目のファイルを上書きできます。

以下はいくつかのデモです。

ファイルが2つ以上で、最後のパラメーターがファイルです。

$ mkdir d1 d2 d3
$ touch a b c e
$ mv *
mv: target 'e' is not a directory

ファイルが3つ以上、最後のパラメータがディレクトリです。

$ 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'

追加の説明

シェルはglob(*)を引数に拡張しますmv。グローブは通常アルファベット順に展開されます。mv常にファイルとディレクトリのリストを確認してください。それは球体自体を決して見ない。

このコマンドは、mv2 種類の移動をサポートします。一つはmv file ... directory。もう一つはmv old-file-name new-file-name(またはmv old-file-name directory/new-file-name)です。

答え2

まず、テストライブラリ(ファイル5個とフォルダ1個)を作成します。

touch file1 file2 file3 file4 file5
mkdir folder

次に、テストコマンドを実行します。このオプションは、-vシェルで実行されているすべてのコマンドをに印刷するように指定しますstderr-xstderrしかし、終わりたい後ろにコマンドは評価されますが、今後実行するためのシェルです。

sh -cxv 'echo mv *'

出力

echo mv *
+ echo mv file1 file2 file3 file4 file5 folder
mv file1 file2 file3 file4 file5 folder

これにより、私がシェルに提供するコマンドがecho mv *シェルが実行するコマンドであることがわかります。後ろに *拡張echo mvファイルとフォルダの両方があります。

デフォルトでは、シェルは拡張されます良い:

sh -cxv 'echo file[1-5]'

出力

echo file[1-5]
+ echo file1 file2 file3 file4 file5
file1 file2 file3 file4 file5

これはglob関数の結果ですset [+-]f

sh -cxvf 'echo file[1-5]'

出力

echo file[1-5]
+ echo 'file[1-5]'
file[1-5]

mv *したがって、単語に拡張されるシェルなど、デフォルトオプションで構成されたシェルでコマンドを実行すると、*現在のディレクトリ内のすべてのファイルの引数のリストがロケールに従ってソートされます。システムexec(ve)コールを実行します。mv (本質的に)このパラメータのリストを追加します。したがって、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ディレクトリの内容を使用して実行します。(空でなく、名前がで始まるファイル/フォルダを含まない場合.パラメータリストとして。mv3つ以上の引数で呼び出されると、POSIXは最終引数がディレクトリとして解釈されることを指定しますln(実際には基本機能の点で非常に似たツールだからです。)

しかし、十分ですecho

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オペランドで指定されたファイルを次の場所に移動する必要があります。宛先ファイル。最初の要約形式は、最後のオペランドが既存のディレクトリに名前を付けず、既存のディレクトリを参照するシンボリックリンクではない場合に使用されます。この場合、ソースファイルディレクトリ以外のファイルの名前を指定し、宛先ファイル末尾の文字で終わる場合、/slashこれはmvエラーと見なされるべきではありません。ソースファイルオペランドが処理されます。

2番目の要約形式では、mvsource_fileオペランドと呼ばれる各ファイルを、source_fileオペランドと呼ばれる既存のディレクトリのターゲットファイルに移動する必要があります。宛先ディレクトリオペランドまたは参照宛先ディレクトリ既存のディレクトリを参照するシンボリックリンクです。各source_fileの宛先パスは、宛先ディレクトリ、単一/slash文字(宛先がaで終わらない場合/slash)、および最後のパス名コンポーネントの接続です。ソースファイル。 2番目の形式は、最後のオペランドが既存のディレクトリに名前を付けるときに使用されます。

したがって、*次のように拡張すると:

  • 2つのファイル

    • ファイルは1つだけでなければならず、renamed2番目のファイルの後の最初から2番目のファイルはunlinked
  • 1つ以上のファイルの後に、1つ以上のファイルへのディレクトリまたはリンクが続きます。

    • 親アイテムの以前のコンテンツがすべて移動されたディレクトリまたはリンクは1つだけである必要があります。
  • その他

    • エラーメッセージを受けて安堵のため息をつくようになります。

答え3

まず、シェルは./*現在のディレクトリ内のすべてのファイルに展開されます(ドットで始まるファイルを除く)。

  • ファイルが存在しないか1つしかない場合:mv失敗
  • 2つのファイルがある場合:最初のファイルは2番目のファイルに移動されます(したがって失われます)。
  • ファイルが2つ以上の場合:
    • 最後のファイルがディレクトリの場合:すべてのファイルがそのディレクトリに移動されます。
    • それ以外の場合はmv失敗します。

答え4

mv *効果は何ですか?

短い答えは次のとおりです。

シェルはワイルドカード文字を*ディレクトリの内容のリストに展開します。これにより、シェルはこのリスト全体をコマンドに渡します。このコマンドは以前見たことがありません*

このコマンドは、mv file1 file2 ... filen directoryfile1...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

関連情報